Theme preview ready.

Also style::color is now copyable, constructed only inside a palette.
Also macOS setup new background ready.
This commit is contained in:
John Preston 2016-12-23 16:21:01 +03:00
parent 1d895cd953
commit ef927c8465
135 changed files with 3516 additions and 1391 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

View file

@ -20,7 +20,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
using "colors.palette"; using "colors.palette";
using "basic_types.style"; TextPalette {
linkFg: color;
monoFg: color;
selectBg: color;
selectOverlay: color;
}
TextStyle {
font: font;
linkFont: font;
linkFontOver: font;
lineHeight: pixels;
}
semibold: "Open Sans Semibold"; semibold: "Open Sans Semibold";
@ -36,18 +48,22 @@ emojiPadding: 1px;
lineWidth: 1px; lineWidth: 1px;
defaultTooltip: Tooltip { defaultTextPalette: TextPalette {
textBg: tooltipBg; linkFg: windowActiveTextFg;
textFg: tooltipFg; monoFg: windowSubTextFg;
textFont: normalFont; selectBg: msgInBgSelected;
textBorder: tooltipBorderFg; selectOverlay: msgSelectOverlay;
textPadding: margins(5px, 2px, 5px, 2px); }
defaultTextStyle: TextStyle {
shift: point(-20px, 20px); font: normalFont;
skip: 10px; linkFont: normalFont;
linkFontOver: font(fsize underline);
widthMax: 800px; lineHeight: 0px;
linesMax: 12; }
semiboldTextStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: font(fsize semibold underline);
} }
shadowToggleDuration: 200; shadowToggleDuration: 200;
@ -75,6 +91,7 @@ activeFadeOutDuration: 3000;
msgMaxWidth: 430px; msgMaxWidth: 430px;
msgFont: font(fsize); msgFont: font(fsize);
msgNameFont: semiboldFont; msgNameFont: semiboldFont;
msgNameStyle: semiboldTextStyle;
msgServiceFont: semiboldFont; msgServiceFont: semiboldFont;
msgServiceNameFont: semiboldFont; msgServiceNameFont: semiboldFont;
msgServicePhotoWidth: 100px; msgServicePhotoWidth: 100px;
@ -102,56 +119,43 @@ msgDateImgDelta: 4px;
msgDateImgPadding: point(8px, 2px); msgDateImgPadding: point(8px, 2px);
msgDateImgCheckSpace: 4px; msgDateImgCheckSpace: 4px;
defaultTextStyle: TextStyle { messageTextStyle: defaultTextStyle;
linkFlags: font(fsize); msgDateTextStyle: defaultTextStyle;
linkFlagsOver: font(fsize underline); serviceTextPalette: TextPalette(defaultTextPalette) {
linkFg: windowActiveTextFg;
linkFgDown: windowActiveTextFg;
monoFg: windowSubTextFg;
selectBg: msgInBgSelected;
selectOverlay: msgSelectOverlay;
lineHeight: 0px;
}
serviceTextStyle: TextStyle(defaultTextStyle) {
linkFlags: msgServiceFont;
linkFlagsOver: font(fsize semibold underline);
linkFg: msgServiceFg; linkFg: msgServiceFg;
linkFgDown: msgServiceFg;
monoFg: msgServiceFg; monoFg: msgServiceFg;
selectBg: msgServiceBgSelected; selectBg: msgServiceBgSelected;
selectOverlay: msgServiceBgSelected; selectOverlay: msgServiceBgSelected;
} }
inTextStyle: TextStyle(defaultTextStyle) { serviceTextStyle: TextStyle(defaultTextStyle) {
font: msgServiceFont;
linkFont: msgServiceFont;
linkFontOver: font(fsize semibold underline);
}
inTextPalette: TextPalette(defaultTextPalette) {
monoFg: msgInMonoFg; monoFg: msgInMonoFg;
selectBg: msgInBgSelected; selectBg: msgInBgSelected;
selectOverlay: msgSelectOverlay; selectOverlay: msgSelectOverlay;
} }
outTextStyle: TextStyle(defaultTextStyle) { outTextPalette: TextPalette(defaultTextPalette) {
monoFg: msgOutMonoFg; monoFg: msgOutMonoFg;
selectBg: msgOutBgSelected; selectBg: msgOutBgSelected;
selectOverlay: msgSelectOverlay; selectOverlay: msgSelectOverlay;
} }
inFwdTextStyle: TextStyle(defaultTextStyle) { fwdTextStyle: TextStyle(semiboldTextStyle) {
linkFlags: semiboldFont; linkFontOver: semiboldFont;
linkFlagsOver: semiboldFont; }
inFwdTextPalette: TextPalette(defaultTextPalette) {
linkFg: msgInServiceFg; linkFg: msgInServiceFg;
linkFgDown: msgInServiceFg;
} }
outFwdTextStyle: TextStyle(inFwdTextStyle) { outFwdTextPalette: TextPalette(defaultTextPalette) {
linkFg: msgOutServiceFg; linkFg: msgOutServiceFg;
linkFgDown: msgOutServiceFg;
} }
inFwdTextStyleSelected: TextStyle(inFwdTextStyle) { inFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
linkFg: msgInServiceFgSelected; linkFg: msgInServiceFgSelected;
linkFgDown: msgInServiceFgSelected;
} }
outFwdTextStyleSelected: TextStyle(inFwdTextStyle) { outFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
linkFg: msgOutServiceFgSelected; linkFg: msgOutServiceFgSelected;
linkFgDown: msgOutServiceFgSelected;
}
mediaviewTextStyle: TextStyle(defaultTextStyle) {
linkFg: mediaviewTextLinkFg;
linkFgDown: mediaviewTextLinkFg;
} }
mediaPadding: margins(0px, 0px, 0px, 0px); mediaPadding: margins(0px, 0px, 0px, 0px);
@ -164,37 +168,13 @@ mediaUnreadSize: 7px;
mediaUnreadSkip: 5px; mediaUnreadSkip: 5px;
mediaUnreadTop: 6px; mediaUnreadTop: 6px;
mediaInStyle: TextStyle(defaultTextStyle) { mediaInPalette: TextPalette(defaultTextPalette) {
linkFg: mediaInFg; linkFg: mediaInFg;
linkFgDown: mediaInFg;
} }
mediaInStyleSelected: TextStyle(defaultTextStyle) { mediaInPaletteSelected: TextPalette(defaultTextPalette) {
linkFg: mediaInFgSelected; linkFg: mediaInFgSelected;
linkFgDown: mediaInFgSelected;
} }
msgFileMenuSize: size(36px, 36px);
msgFileSize: 44px;
msgFilePadding: margins(14px, 12px, 11px, 12px);
msgFileThumbSize: 72px;
msgFileThumbPadding: margins(10px, 10px, 14px, 10px);
msgFileThumbNameTop: 12px;
msgFileThumbStatusTop: 32px;
msgFileThumbLinkTop: 60px;
msgFileNameTop: 16px;
msgFileStatusTop: 37px;
msgFileMinWidth: 294px;
msgFileOverDuration: 200;
msgFileRadialLine: 3px;
msgVideoSize: size(320px, 240px);
msgWaveformBar: 2px;
msgWaveformSkip: 1px;
msgWaveformMin: 2px;
msgWaveformMax: 20px;
textRectMargins: margins(-2px, -1px, -2px, -1px); textRectMargins: margins(-2px, -1px, -2px, -1px);
searchedBarHeight: 32px; searchedBarHeight: 32px;
@ -229,44 +209,6 @@ maxStickerSize: 256px;
maxGifSize: 320px; maxGifSize: 320px;
maxSignatureSize: 144px; maxSignatureSize: 144px;
mvThickFont: semiboldFont;
mvFont: normalFont;
mvTextLeft: 16px;
mvTextSkip: 10px;
mvHeaderTop: 48px;
mvTextTop: 24px;
mvTextOpacity: 0.5;
mvTextOverOpacity: 1;
mvIconOpacity: 0.45;
mvIconOverOpacity: 1;
mvControlBgOpacity: 0.3;
mvControlMargin: 0px;
mvControlSize: 90px;
mvIconSize: size(60px, 56px);
mvWaitHide: 2000;
mvHideDuration: 1000;
mvShowDuration: 200;
mvFadeDuration: 150;
mvDeltaFromLastAction: 5px;
mvSwipeDistance: 80px;
mvCaptionPadding: margins(18px, 10px, 18px, 10px);
mvCaptionMargin: size(11px, 11px);
mvCaptionRadius: 2px;
mvCaptionFont: font(fsize);
medviewSaveMsgCheck: icon {{ "mediaview_save_check", mediaviewSaveMsgFg }};
medviewSaveMsgFont: font(16px);
medviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
medviewSaveMsgCheckPos: point(23px, 21px);
medviewSaveMsgShowing: 200;
medviewSaveMsgShown: 2000;
medviewSaveMsgHiding: 2500;
radialSize: size(50px, 50px); radialSize: size(50px, 50px);
radialLine: 3px; radialLine: 3px;
radialDuration: 350; radialDuration: 350;
@ -285,11 +227,13 @@ locationSize: size(320px, 240px);
webPageLeft: 10px; webPageLeft: 10px;
webPageBar: 2px; webPageBar: 2px;
webPageTitleFont: semiboldFont; webPageTitleFont: semiboldFont;
webPageTitleStyle: semiboldTextStyle;
webPageTitleOutFg: historyTextOutFg; webPageTitleOutFg: historyTextOutFg;
webPageTitleInFg: historyTextInFg; webPageTitleInFg: historyTextInFg;
webPageDescriptionOutFg: historyTextOutFg; webPageDescriptionOutFg: historyTextOutFg;
webPageDescriptionInFg: historyTextInFg; webPageDescriptionInFg: historyTextInFg;
webPageDescriptionFont: normalFont; webPageDescriptionFont: normalFont;
webPageDescriptionStyle: defaultTextStyle;
webPagePhotoSize: 100px; webPagePhotoSize: 100px;
webPagePhotoDelta: 8px; webPagePhotoDelta: 8px;
@ -315,7 +259,7 @@ inlineRowFileDescriptionTop: 23px;
inlineResultsMinWidth: 64px; inlineResultsMinWidth: 64px;
inlineDurationMargin: 3px; inlineDurationMargin: 3px;
toastFont: normalFont; toastTextStyle: defaultTextStyle;
toastMaxWidth: 480px; toastMaxWidth: 480px;
toastMinMargin: 13px; toastMinMargin: 13px;
toastPadding: margins(19px, 13px, 19px, 12px); toastPadding: margins(19px, 13px, 19px, 12px);

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -988,6 +988,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_mediaview_saved" = "Image was saved to your [c]Downloads[/c] folder"; "lng_mediaview_saved" = "Image was saved to your [c]Downloads[/c] folder";
"lng_theme_preview_title" = "Theme Preview";
"lng_theme_preview_generating" = "Generating color theme preview...";
"lng_theme_preview_invalid" = "Invalid data in this theme file.";
"lng_theme_preview_apply" = "Apply this theme";
"lng_new_authorization" = "{name},\nWe detected a login into your account from a new device on {day}, {date} at {time}\n\nDevice: {device}\nLocation: {location}\n\nIf this wasn't you, you can go to Settings — Show all sessions and terminate that session.\n\nIf you think that somebody logged in to your account against your will, you can enable two-step verification in Settings.\n\nSincerely,\nThe Telegram Team"; "lng_new_authorization" = "{name},\nWe detected a login into your account from a new device on {day}, {date} at {time}\n\nDevice: {device}\nLocation: {location}\n\nIf this wasn't you, you can go to Settings — Show all sessions and terminate that session.\n\nIf you think that somebody logged in to your account against your will, you can enable two-step verification in Settings.\n\nSincerely,\nThe Telegram Team";
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}"; "lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";

View file

@ -25,7 +25,7 @@ windowBg: #ffffff;
windowFg: #000000; windowFg: #000000;
windowBgOver: #f1f1f1; windowBgOver: #f1f1f1;
windowBgRipple: #e5e5e5; windowBgRipple: #e5e5e5;
windowFgOver: windowFg; windowFgOver: #000000; // windowBgOver;
windowSubTextFg: #999999; windowSubTextFg: #999999;
windowSubTextFgOver: #919191; windowSubTextFgOver: #919191;
windowBoldFg: #222222; windowBoldFg: #222222;
@ -37,34 +37,34 @@ windowShadowFg: #000000;
windowShadowFgFallback: #f1f1f1; windowShadowFgFallback: #f1f1f1;
shadowFg: #00000018; shadowFg: #00000018;
slideFadeOutBg: #0000003c; slideFadeOutBg: #0000003c;
slideFadeOutShadowFg: windowShadowFg; slideFadeOutShadowFg: #000000; // windowShadowFgFallback;
imageBg: #000000; imageBg: #000000;
imageBgTransparent: #ffffff; imageBgTransparent: #ffffff;
activeButtonBg: windowBgActive; activeButtonBg: #40a7e3; // windowFgActive;
activeButtonBgOver: #39a5db; activeButtonBgOver: #39a5db;
activeButtonBgRipple: #2095d0; activeButtonBgRipple: #2095d0;
activeButtonFg: windowFgActive; activeButtonFg: #ffffff; // windowActiveTextFg;
activeButtonFgOver: activeButtonFg; activeButtonFgOver: activeButtonFgOver;
activeButtonSecondaryFg: #cceeff; activeButtonSecondaryFg: #cceeff;
activeButtonSecondaryFgOver: activeButtonSecondaryFg; activeButtonSecondaryFgOver: activeButtonSecondaryFgOver;
activeLineFg: #37a1de; activeLineFg: #37a1de;
activeLineFgError: #e48383; activeLineFgError: #e48383;
lightButtonBg: windowBg; lightButtonBg: #ffffff; // windowFg;
lightButtonBgOver: #e3f1fa; lightButtonBgOver: #e3f1fa;
lightButtonBgRipple: #c9e4f6; lightButtonBgRipple: #c9e4f6;
lightButtonFg: windowActiveTextFg; lightButtonFg: #168acd; // windowShadowFg;
lightButtonFgOver: lightButtonFg; lightButtonFgOver: lightButtonFgOver;
attentionButtonFg: #d14e4e; attentionButtonFg: #d14e4e;
attentionButtonFgOver: #d14e4e; attentionButtonFgOver: #d14e4e;
attentionButtonBgOver: #fcdfde; attentionButtonBgOver: #fcdfde;
attentionButtonBgRipple: #f4c3c2; attentionButtonBgRipple: #f4c3c2;
outlineButtonBg: windowBg; outlineButtonBg: #ffffff; // windowFg;
outlineButtonBgOver: lightButtonBgOver; outlineButtonBgOver: #e3f1fa; // lightButtonBgRipple;
outlineButtonOutlineFg: windowBgActive; outlineButtonOutlineFg: #40a7e3; // windowFgActive;
outlineButtonBgRipple: lightButtonBgRipple; outlineButtonBgRipple: #c9e4f6; // lightButtonFg;
menuBg: windowBg; menuBg: #ffffff; // windowFg;
menuBgOver: windowBgOver; menuBgOver: #f1f1f1; // windowBgRipple;
menuBgRipple: windowBgRipple; menuBgRipple: #e5e5e5; // windowFgOver;
menuIconFg: #a8a8a8; menuIconFg: #a8a8a8;
menuIconFgOver: #999999; menuIconFgOver: #999999;
menuSubmenuArrowFg: #373737; menuSubmenuArrowFg: #373737;
@ -76,25 +76,25 @@ scrollBg: #0000001a;
scrollBgOver: #0000002c; scrollBgOver: #0000002c;
smallCloseIconFg: #c7c7c7; smallCloseIconFg: #c7c7c7;
smallCloseIconFgOver: #a3a3a3; smallCloseIconFgOver: #a3a3a3;
radialFg: windowFgActive; radialFg: #ffffff; // windowActiveTextFg;
radialBg: #00000056; radialBg: #00000056;
placeholderFg: windowSubTextFg; placeholderFg: #999999; // windowSubTextFgOver;
placeholderFgActive: #aaaaaa; placeholderFgActive: #aaaaaa;
inputBorderFg: #e0e0e0; inputBorderFg: #e0e0e0;
filterInputBorderFg: #54c3f3; filterInputBorderFg: #54c3f3;
checkboxFg: #b3b3b3; checkboxFg: #b3b3b3;
sliderBgInactive: #e1eaef; sliderBgInactive: #e1eaef;
sliderBgActive: windowBgActive; sliderBgActive: #40a7e3; // windowFgActive;
tooltipBg: #eef2f5; tooltipBg: #eef2f5;
tooltipFg: #5d6c80; tooltipFg: #5d6c80;
tooltipBorderFg: #c9d1db; tooltipBorderFg: #c9d1db;
titleBg: windowBgOver; titleBg: #f1f1f1; // windowBgRipple;
titleShadow: #00000003; titleShadow: #00000003;
titleButtonFg: #ababab; titleButtonFg: #ababab;
titleButtonBgOver: #e5e5e5; titleButtonBgOver: #e5e5e5;
titleButtonFgOver: #9a9a9a; titleButtonFgOver: #9a9a9a;
titleButtonCloseBgOver: #e81123; titleButtonCloseBgOver: #e81123;
titleButtonCloseFgOver: windowFgActive; titleButtonCloseFgOver: #ffffff; // windowActiveTextFg;
titleFgActive: #3e3c3e; titleFgActive: #3e3c3e;
titleFg: #acacac; titleFg: #acacac;
trayCounterBg: #f23c34; trayCounterBg: #f23c34;
@ -103,32 +103,32 @@ trayCounterFg: #ffffff;
trayCounterBgMacInvert: #ffffff; trayCounterBgMacInvert: #ffffff;
trayCounterFgMacInvert: #ffffff01; trayCounterFgMacInvert: #ffffff01;
layerBg: #0000007f; layerBg: #0000007f;
cancelIconFg: menuIconFg; cancelIconFg: #a8a8a8; // menuIconFgOver;
cancelIconFgOver: menuIconFgOver; cancelIconFgOver: #999999; // menuSubmenuArrowFg;
boxBg: windowBg; boxBg: #ffffff; // windowFg;
boxTextFg: windowFg; boxTextFg: #000000; // windowBgOver;
boxTextFgGood: #4ab44a; boxTextFgGood: #4ab44a;
boxTextFgError: #d84d4d; boxTextFgError: #d84d4d;
boxTitleFg: #404040; boxTitleFg: #404040;
boxSearchBg: boxBg; boxSearchBg: #ffffff; // boxTextFg;
boxSearchCancelIconFg: cancelIconFg; boxSearchCancelIconFg: #a8a8a8; // cancelIconFgOver;
boxSearchCancelIconFgOver: cancelIconFgOver; boxSearchCancelIconFgOver: #999999; // boxBg;
boxTitleAdditionalFg: #808080; boxTitleAdditionalFg: #808080;
boxTitleCloseFg: cancelIconFg; boxTitleCloseFg: #a8a8a8; // cancelIconFgOver;
boxTitleCloseFgOver: cancelIconFgOver; boxTitleCloseFgOver: #999999; // boxBg;
membersAboutLimitFg: windowSubTextFgOver; membersAboutLimitFg: #919191; // windowBoldFg;
contactsBg: windowBg; contactsBg: #ffffff; // windowFg;
contactsBgOver: windowBgOver; contactsBgOver: #f1f1f1; // windowBgRipple;
contactsNameFg: boxTextFg; contactsNameFg: #000000; // boxTextFgGood;
contactsStatusFg: windowSubTextFg; contactsStatusFg: #999999; // windowSubTextFgOver;
contactsStatusFgOver: windowSubTextFgOver; contactsStatusFgOver: #919191; // windowBoldFg;
contactsStatusFgOnline: windowActiveTextFg; contactsStatusFgOnline: #168acd; // windowShadowFg;
photoCropFadeBg: layerBg; photoCropFadeBg: #0000007f; // cancelIconFg;
photoCropPointFg: #ffffff7f; photoCropPointFg: #ffffff7f;
introBg: windowBg; introBg: #ffffff; // windowFg;
introTitleFg: windowBoldFg; introTitleFg: windowBoldFgOver;
introDescriptionFg: windowSubTextFg; introDescriptionFg: #999999; // windowSubTextFgOver;
introErrorFg: windowSubTextFg; introErrorFg: #999999; // windowSubTextFgOver;
introCoverTopBg: #0f89d0; introCoverTopBg: #0f89d0;
introCoverBottomBg: #39b0f0; introCoverBottomBg: #39b0f0;
introCoverIconsFg: #5ec6ff; introCoverIconsFg: #5ec6ff;
@ -136,83 +136,83 @@ introCoverPlaneTrace: #5ec6ff69;
introCoverPlaneInner: #c6d8e8; introCoverPlaneInner: #c6d8e8;
introCoverPlaneOuter: #a1bed4; introCoverPlaneOuter: #a1bed4;
introCoverPlaneTop: #ffffff; introCoverPlaneTop: #ffffff;
dialogsMenuIconFg: menuIconFg; dialogsMenuIconFg: #a8a8a8; // menuIconFgOver;
dialogsMenuIconFgOver: menuIconFgOver; dialogsMenuIconFgOver: #999999; // menuSubmenuArrowFg;
dialogsBg: windowBg; dialogsBg: #ffffff; // windowFg;
dialogsNameFg: windowBoldFg; dialogsNameFg: windowBoldFgOver;
dialogsChatIconFg: dialogsNameFg; dialogsChatIconFg: dialogsChatIconFg;
dialogsDateFg: windowSubTextFg; dialogsDateFg: #999999; // windowSubTextFgOver;
dialogsTextFg: windowSubTextFg; dialogsTextFg: #999999; // windowSubTextFgOver;
dialogsTextFgService: windowActiveTextFg; dialogsTextFgService: #168acd; // windowShadowFg;
dialogsDraftFg: #dd4b39; dialogsDraftFg: #dd4b39;
dialogsVerifiedIconBg: windowBgActive; dialogsVerifiedIconBg: #40a7e3; // windowFgActive;
dialogsVerifiedIconFg: windowFgActive; dialogsVerifiedIconFg: #ffffff; // windowActiveTextFg;
dialogsSendingIconFg: #c1c1c1; dialogsSendingIconFg: #c1c1c1;
dialogsSentIconFg: #5dc452; dialogsSentIconFg: #5dc452;
dialogsUnreadBg: windowBgActive; dialogsUnreadBg: #40a7e3; // windowFgActive;
dialogsUnreadBgMuted: #bbbbbb; dialogsUnreadBgMuted: #bbbbbb;
dialogsUnreadFg: windowFgActive; dialogsUnreadFg: #ffffff; // windowActiveTextFg;
dialogsBgOver: windowBgOver; dialogsBgOver: #f1f1f1; // windowBgRipple;
dialogsNameFgOver: windowBoldFgOver; dialogsNameFgOver: #222222; // windowBgActive;
dialogsChatIconFgOver: dialogsNameFgOver; dialogsChatIconFgOver: dialogsChatIconFgOver;
dialogsDateFgOver: windowSubTextFgOver; dialogsDateFgOver: #919191; // windowBoldFg;
dialogsTextFgOver: windowSubTextFgOver; dialogsTextFgOver: #919191; // windowBoldFg;
dialogsTextFgServiceOver: dialogsTextFgService; dialogsTextFgServiceOver: #168acd; // dialogsDraftFg;
dialogsDraftFgOver: dialogsDraftFg; dialogsDraftFgOver: #dd4b39; // dialogsVerifiedIconBg;
dialogsVerifiedIconBgOver: dialogsVerifiedIconBg; dialogsVerifiedIconBgOver: #40a7e3; // dialogsVerifiedIconFg;
dialogsVerifiedIconFgOver: dialogsVerifiedIconFg; dialogsVerifiedIconFgOver: #ffffff; // dialogsSendingIconFg;
dialogsSendingIconFgOver: dialogsSendingIconFg; dialogsSendingIconFgOver: #c1c1c1; // dialogsSentIconFg;
dialogsSentIconFgOver: dialogsSentIconFg; dialogsSentIconFgOver: #5dc452; // dialogsUnreadBg;
dialogsUnreadBgOver: dialogsUnreadBg; dialogsUnreadBgOver: #40a7e3; // dialogsUnreadBgMuted;
dialogsUnreadBgMutedOver: dialogsUnreadBgMuted; dialogsUnreadBgMutedOver: #bbbbbb; // dialogsUnreadFg;
dialogsUnreadFgOver: dialogsUnreadFg; dialogsUnreadFgOver: #ffffff; // dialogsBgOver;
dialogsBgActive: #419fd9; dialogsBgActive: #419fd9;
dialogsNameFgActive: windowFgActive; dialogsNameFgActive: #ffffff; // windowActiveTextFg;
dialogsChatIconFgActive: dialogsNameFgActive; dialogsChatIconFgActive: dialogsChatIconFgActive;
dialogsDateFgActive: windowFgActive; dialogsDateFgActive: #ffffff; // windowActiveTextFg;
dialogsTextFgActive: windowFgActive; dialogsTextFgActive: #ffffff; // windowActiveTextFg;
dialogsTextFgServiceActive: dialogsTextFgActive; dialogsTextFgServiceActive: dialogsTextFgServiceActive;
dialogsDraftFgActive: #c6e1f7; dialogsDraftFgActive: #c6e1f7;
dialogsVerifiedIconBgActive: dialogsTextFgActive; dialogsVerifiedIconBgActive: dialogsTextFgServiceActive;
dialogsVerifiedIconFgActive: dialogsBgActive; dialogsVerifiedIconFgActive: #419fd9; // dialogsNameFgActive;
dialogsSendingIconFgActive: #ffffff99; dialogsSendingIconFgActive: #ffffff99;
dialogsSentIconFgActive: dialogsTextFgActive; dialogsSentIconFgActive: dialogsTextFgServiceActive;
dialogsUnreadBgActive: dialogsTextFgActive; dialogsUnreadBgActive: dialogsTextFgServiceActive;
dialogsUnreadBgMutedActive: dialogsDraftFgActive; dialogsUnreadBgMutedActive: #c6e1f7; // dialogsVerifiedIconBgActive;
dialogsUnreadFgActive: dialogsBgActive; dialogsUnreadFgActive: #419fd9; // dialogsNameFgActive;
dialogsForwardBg: dialogsBgActive; dialogsForwardBg: #419fd9; // dialogsNameFgActive;
dialogsForwardFg: dialogsNameFgActive; dialogsForwardFg: dialogsChatIconFgActive;
searchedBarBg: windowBgOver; searchedBarBg: #f1f1f1; // windowBgRipple;
searchedBarBorder: shadowFg; searchedBarBorder: #00000018; // slideFadeOutBg;
searchedBarFg: windowSubTextFgOver; searchedBarFg: #919191; // windowBoldFg;
topBarBg: windowBg; topBarBg: #ffffff; // windowFg;
emojiPanBg: windowBg; emojiPanBg: #ffffff; // windowFg;
emojiPanCategories: #f7f7f7; // windowBg; emojiPanCategories: #f7f7f7; // windowFg;
emojiPanHeaderFg: windowSubTextFg; emojiPanHeaderFg: #999999; // windowSubTextFgOver;
emojiPanHeaderBg: #fffffff2; // emojiPanBg; emojiPanHeaderBg: #fffffff2; // emojiPanCategories;
stickerPanDeleteBg: #000000cc; stickerPanDeleteBg: #000000cc;
stickerPanDeleteFg: windowFgActive; stickerPanDeleteFg: #ffffff; // windowActiveTextFg;
stickerPreviewBg: #ffffffb0; stickerPreviewBg: #ffffffb0;
historyTextInFg: windowFg; historyTextInFg: #000000; // windowBgOver;
historyTextOutFg: windowFg; historyTextOutFg: #000000; // windowBgOver;
historyCaptionInFg: historyTextInFg; historyCaptionInFg: historyTextOutFg;
historyCaptionOutFg: historyTextOutFg; historyCaptionOutFg: historyCaptionInFg;
historyFileNameInFg: historyTextInFg; historyFileNameInFg: historyTextOutFg;
historyFileNameOutFg: historyTextOutFg; historyFileNameOutFg: historyCaptionInFg;
historyOutIconFg: dialogsSentIconFg; historyOutIconFg: #5dc452; // dialogsUnreadBg;
historyOutIconFgSelected: #4da79f; historyOutIconFgSelected: #4da79f;
historyIconFgInverted: windowFgActive; historyIconFgInverted: #ffffff; // windowActiveTextFg;
historySendingOutIconFg: #98d292; historySendingOutIconFg: #98d292;
historySendingInIconFg: #a0adb5; historySendingInIconFg: #a0adb5;
historySendingInvertedIconFg: #ffffffc8; historySendingInvertedIconFg: #ffffffc8;
historySystemBg: #89a0b47f; historySystemBg: #89a0b47f;
historySystemBgSelected: #bbc8d4a2; historySystemBgSelected: #bbc8d4a2;
historySystemFg: windowFgActive; historySystemFg: #ffffff; // windowActiveTextFg;
historyUnreadBarBg: #fcfbfa; historyUnreadBarBg: #fcfbfa;
historyUnreadBarBorder: shadowFg; historyUnreadBarBorder: #00000018; // slideFadeOutBg;
historyUnreadBarFg: #538bb4; historyUnreadBarFg: #538bb4;
historyForwardChooseBg: #0000004c; historyForwardChooseBg: #0000004c;
historyForwardChooseFg: windowFgActive; historyForwardChooseFg: #ffffff; // windowActiveTextFg;
historyPeer1NameFg: #c03d33; historyPeer1NameFg: #c03d33;
historyPeer1UserpicBg: #ed9482; historyPeer1UserpicBg: #ed9482;
historyPeer1UserpicFg: #d3644b; historyPeer1UserpicFg: #d3644b;
@ -222,7 +222,7 @@ historyPeer2UserpicFg: #75c057;
historyPeer3NameFg: #d09306; historyPeer3NameFg: #d09306;
historyPeer3UserpicBg: #efd289; historyPeer3UserpicBg: #efd289;
historyPeer3UserpicFg: #e4a861; historyPeer3UserpicFg: #e4a861;
historyPeer4NameFg: windowActiveTextFg; historyPeer4NameFg: #168acd; // windowShadowFg;
historyPeer4UserpicBg: #8fbfe9; historyPeer4UserpicBg: #8fbfe9;
historyPeer4UserpicFg: #649fd3; historyPeer4UserpicFg: #649fd3;
historyPeer5NameFg: #8544d6; historyPeer5NameFg: #8544d6;
@ -241,14 +241,14 @@ historyScrollBarBg: #556e837a;
historyScrollBarBgOver: #556e83bc; historyScrollBarBgOver: #556e83bc;
historyScrollBg: #556e834c; historyScrollBg: #556e834c;
historyScrollBgOver: #556e836b; historyScrollBgOver: #556e836b;
msgInBg: windowBg; msgInBg: #ffffff; // windowFg;
msgInBgSelected: #c2dcf2; msgInBgSelected: #c2dcf2;
msgOutBg: #effdde; msgOutBg: #effdde;
msgOutBgSelected: #b7dbdb; msgOutBgSelected: #b7dbdb;
msgSelectOverlay: #358cd44c; msgSelectOverlay: #358cd44c;
msgStickerOverlay: #358cd47f; msgStickerOverlay: #358cd47f;
msgInServiceFg: windowActiveTextFg; msgInServiceFg: #168acd; // windowShadowFg;
msgInServiceFgSelected: windowActiveTextFg; msgInServiceFgSelected: #168acd; // windowShadowFg;
msgOutServiceFg: #3a8e26; msgOutServiceFg: #3a8e26;
msgOutServiceFgSelected: #367570; msgOutServiceFgSelected: #367570;
msgInShadow: #748ea229; msgInShadow: #748ea229;
@ -259,25 +259,25 @@ msgInDateFg: #a0acb6;
msgInDateFgSelected: #6a9cc5; msgInDateFgSelected: #6a9cc5;
msgOutDateFg: #6cc264; msgOutDateFg: #6cc264;
msgOutDateFgSelected: #50a79c; msgOutDateFgSelected: #50a79c;
msgServiceFg: windowFgActive; msgServiceFg: #ffffff; // windowActiveTextFg;
msgServiceBg: #556e837f; msgServiceBg: #556e837f;
msgServiceBgSelected: #8ca0b3a2; msgServiceBgSelected: #8ca0b3a2;
msgInReplyBarColor: activeLineFg; msgInReplyBarColor: #37a1de; // activeLineFgError;
msgInReplyBarSelColor: activeLineFg; msgInReplyBarSelColor: #37a1de; // activeLineFgError;
msgOutReplyBarColor: historyOutIconFg; msgOutReplyBarColor: #5dc452; // historyOutIconFgSelected;
msgOutReplyBarSelColor: historyOutIconFgSelected; msgOutReplyBarSelColor: #4da79f; // historyIconFgInverted;
msgImgReplyBarColor: msgServiceFg; msgImgReplyBarColor: #ffffff; // msgServiceBg;
msgInMonoFg: #4e7391; msgInMonoFg: #4e7391;
msgOutMonoFg: #469165; msgOutMonoFg: #469165;
msgDateImgFg: msgServiceFg; msgDateImgFg: #ffffff; // msgServiceBg;
msgDateImgBg: #00000054; msgDateImgBg: #00000054;
msgDateImgBgOver: #00000074; msgDateImgBgOver: #00000074;
msgDateImgBgSelected: #1c4a7187; msgDateImgBgSelected: #1c4a7187;
msgFileThumbLinkInFg: lightButtonFg; msgFileThumbLinkInFg: lightButtonFgOver;
msgFileThumbLinkInFgSelected: lightButtonFgOver; msgFileThumbLinkInFgSelected: #168acd; // attentionButtonFg;
msgFileThumbLinkOutFg: #5eba5b; msgFileThumbLinkOutFg: #5eba5b;
msgFileThumbLinkOutFgSelected: #31a298; msgFileThumbLinkOutFgSelected: #31a298;
msgFileInBg: windowBgActive; msgFileInBg: #40a7e3; // windowFgActive;
msgFileInBgOver: #4eade3; msgFileInBgOver: #4eade3;
msgFileInBgSelected: #51a3d3; msgFileInBgSelected: #51a3d3;
msgFileOutBg: #78c67f; msgFileOutBg: #78c67f;
@ -299,7 +299,7 @@ msgFile4Bg: #efc274;
msgFile4BgDark: #e6a561; msgFile4BgDark: #e6a561;
msgFile4BgOver: #dc9c5a; msgFile4BgOver: #dc9c5a;
msgFile4BgSelected: #b19d84; msgFile4BgSelected: #b19d84;
msgWaveformInActive: windowBgActive; msgWaveformInActive: #40a7e3; // windowFgActive;
msgWaveformInActiveSelected: #51a3d3; msgWaveformInActiveSelected: #51a3d3;
msgWaveformInInactive: #d4dee6; msgWaveformInInactive: #d4dee6;
msgWaveformInInactiveSelected: #9cc1e1; msgWaveformInInactiveSelected: #9cc1e1;
@ -308,81 +308,81 @@ msgWaveformOutActiveSelected: #6badad;
msgWaveformOutInactive: #b3e2b4; msgWaveformOutInactive: #b3e2b4;
msgWaveformOutInactiveSelected: #91c3c3; msgWaveformOutInactiveSelected: #91c3c3;
msgBotKbOverBgAdd: #ffffff20; msgBotKbOverBgAdd: #ffffff20;
msgBotKbIconFg: msgServiceFg; msgBotKbIconFg: #ffffff; // msgServiceBg;
msgBotKbRippleBg: #00000020; msgBotKbRippleBg: #00000020;
mediaInFg: msgInDateFg; mediaInFg: #a0acb6; // msgInDateFgSelected;
mediaInFgSelected: msgInDateFgSelected; mediaInFgSelected: #6a9cc5; // msgOutDateFg;
mediaOutFg: msgOutDateFg; mediaOutFg: #6cc264; // msgOutDateFgSelected;
mediaOutFgSelected: msgOutDateFgSelected; mediaOutFgSelected: #50a79c; // msgServiceFg;
youtubePlayIconBg: #e83131c8; youtubePlayIconBg: #e83131c8;
youtubePlayIconFg: windowFgActive; youtubePlayIconFg: #ffffff; // windowActiveTextFg;
videoPlayIconBg: #0000007f; videoPlayIconBg: #0000007f;
videoPlayIconFg: #ffffff; videoPlayIconFg: #ffffff;
toastBg: #000000b2; toastBg: #000000b2;
toastFg: windowFgActive; toastFg: #ffffff; // windowActiveTextFg;
reportSpamBg: emojiPanHeaderBg; reportSpamBg: #fffffff2; // stickerPanDeleteBg;
reportSpamFg: windowFg; reportSpamFg: #000000; // windowBgOver;
historyToDownShadow: #00000040; historyToDownShadow: #00000040;
historyComposeAreaBg: msgInBg; historyComposeAreaBg: #ffffff; // msgInBgSelected;
historyComposeAreaFg: historyTextInFg; historyComposeAreaFg: historyTextOutFg;
historyComposeAreaFgService: msgInDateFg; historyComposeAreaFgService: #a0acb6; // msgInDateFgSelected;
historyComposeIconFg: menuIconFg; historyComposeIconFg: #a8a8a8; // menuIconFgOver;
historyComposeIconFgOver: menuIconFgOver; historyComposeIconFgOver: #999999; // menuSubmenuArrowFg;
historySendIconFg: windowBgActive; historySendIconFg: #40a7e3; // windowFgActive;
historySendIconFgOver: windowBgActive; historySendIconFgOver: #40a7e3; // windowFgActive;
historyPinnedBg: historyComposeAreaBg; historyPinnedBg: #ffffff; // historyComposeAreaFg;
historyReplyBg: historyComposeAreaBg; historyReplyBg: #ffffff; // historyComposeAreaFg;
historyReplyCancelFg: cancelIconFg; historyReplyCancelFg: #a8a8a8; // cancelIconFgOver;
historyReplyCancelFgOver: cancelIconFgOver; historyReplyCancelFgOver: #999999; // boxBg;
historyComposeButtonBg: historyComposeAreaBg; historyComposeButtonBg: #ffffff; // historyComposeAreaFg;
historyComposeButtonBgOver: windowBgOver; historyComposeButtonBgOver: #f1f1f1; // windowBgRipple;
historyComposeButtonBgRipple: windowBgRipple; historyComposeButtonBgRipple: #e5e5e5; // windowFgOver;
overviewCheckBg: #00000040; overviewCheckBg: #00000040;
overviewCheckFg: windowBg; overviewCheckFg: #ffffff; // windowFg;
overviewCheckFgActive: windowBg; overviewCheckFgActive: #ffffff; // windowFg;
overviewPhotoSelectOverlay: #40ace333; overviewPhotoSelectOverlay: #40ace333;
profileStatusFgOver: #7c99b2; profileStatusFgOver: #7c99b2;
notificationsBoxMonitorFg: windowFg; notificationsBoxMonitorFg: #000000; // windowBgOver;
notificationsBoxScreenBg: dialogsBgActive; notificationsBoxScreenBg: #419fd9; // dialogsNameFgActive;
notificationSampleUserpicFg: windowBgActive; notificationSampleUserpicFg: #40a7e3; // windowFgActive;
notificationSampleCloseFg: #d7d7d7; // windowSubTextFg; notificationSampleCloseFg: #d7d7d7; // windowSubTextFgOver;
notificationSampleTextFg: #d7d7d7; // windowSubTextFg; notificationSampleTextFg: #d7d7d7; // windowSubTextFgOver;
notificationSampleNameFg: #939393; // windowSubTextFg; notificationSampleNameFg: #939393; // windowSubTextFgOver;
mainMenuBg: windowBg; mainMenuBg: #ffffff; // windowFg;
mainMenuCoverBg: dialogsBgActive; mainMenuCoverBg: #419fd9; // dialogsNameFgActive;
mainMenuCoverFg: windowFgActive; mainMenuCoverFg: #ffffff; // windowActiveTextFg;
mediaPlayerBg: windowBg; mediaPlayerBg: #ffffff; // windowFg;
mediaPlayerActiveFg: windowBgActive; mediaPlayerActiveFg: #40a7e3; // windowFgActive;
mediaPlayerInactiveFg: sliderBgInactive; mediaPlayerInactiveFg: #e1eaef; // sliderBgActive;
mediaPlayerDisabledFg: #9dd1ef; mediaPlayerDisabledFg: #9dd1ef;
mediaviewFileBg: windowBg; mediaviewFileBg: #ffffff; // windowFg;
mediaviewFileNameFg: windowFg; mediaviewFileNameFg: #000000; // windowBgOver;
mediaviewFileSizeFg: windowSubTextFg; mediaviewFileSizeFg: #999999; // windowSubTextFgOver;
mediaviewFileRedCornerFg: #d55959; mediaviewFileRedCornerFg: #d55959;
mediaviewFileYellowCornerFg: #e8a659; mediaviewFileYellowCornerFg: #e8a659;
mediaviewFileGreenCornerFg: #49a957; mediaviewFileGreenCornerFg: #49a957;
mediaviewFileBlueCornerFg: #599dcf; mediaviewFileBlueCornerFg: #599dcf;
mediaviewFileExtFg: activeButtonFg; mediaviewFileExtFg: activeButtonFgOver;
mediaviewMenuBg: #383838; mediaviewMenuBg: #383838;
mediaviewMenuBgOver: #505050; mediaviewMenuBgOver: #505050;
mediaviewMenuBgRipple: #676767; mediaviewMenuBgRipple: #676767;
mediaviewMenuFg: windowFgActive; mediaviewMenuFg: #ffffff; // windowActiveTextFg;
mediaviewBg: #222222eb; mediaviewBg: #222222eb;
mediaviewVideoBg: imageBg; mediaviewVideoBg: #000000; // imageBgTransparent;
mediaviewControlBg: #0000003c; mediaviewControlBg: #0000003c;
mediaviewControlFg: windowFgActive; mediaviewControlFg: #ffffff; // windowActiveTextFg;
mediaviewCaptionBg: #11111180; mediaviewCaptionBg: #11111180;
mediaviewCaptionFg: mediaviewControlFg; mediaviewCaptionFg: #ffffff; // mediaviewCaptionBg;
mediaviewTextLinkFg: #91d9ff; mediaviewTextLinkFg: #91d9ff;
mediaviewSaveMsgBg: toastBg; mediaviewSaveMsgBg: #000000b2; // toastFg;
mediaviewSaveMsgFg: toastFg; mediaviewSaveMsgFg: #ffffff; // reportSpamBg;
mediaviewPlaybackActive: #c7c7c7; mediaviewPlaybackActive: #c7c7c7;
mediaviewPlaybackInactive: #252525; mediaviewPlaybackInactive: #252525;
mediaviewPlaybackActiveOver: #ffffff; mediaviewPlaybackActiveOver: #ffffff;
mediaviewPlaybackInactiveOver: #474747; mediaviewPlaybackInactiveOver: #474747;
mediaviewPlaybackProgressFg: #ffffffc7; mediaviewPlaybackProgressFg: #ffffffc7;
mediaviewPlaybackIconFg: mediaviewPlaybackActive; mediaviewPlaybackIconFg: #c7c7c7; // mediaviewPlaybackInactive;
mediaviewPlaybackIconFgOver: mediaviewPlaybackActiveOver; mediaviewPlaybackIconFgOver: #ffffff; // mediaviewPlaybackInactiveOver;
mediaviewTransparentBg: #ffffff; mediaviewTransparentBg: #ffffff;
mediaviewTransparentFg: #cccccc; mediaviewTransparentFg: #cccccc;
notificationBg: windowBg; notificationBg: #ffffff; // windowFg;

View file

@ -8,6 +8,7 @@
<file>art/bg_initial.png</file> <file>art/bg_initial.png</file>
<file>art/icon256.png</file> <file>art/icon256.png</file>
<file>art/iconbig256.png</file> <file>art/iconbig256.png</file>
<file>art/sunrise.jpg</file>
</qresource> </qresource>
<qresource prefix="/qt-project.org"> <qresource prefix="/qt-project.org">
<file>qmime/freedesktop.org.xml</file> <file>qmime/freedesktop.org.xml</file>

View file

@ -1,5 +1,2 @@
<RCC> <RCC>
<qresource prefix="/gui">
<file>art/osxtray.png</file>
</qresource>
</RCC> </RCC>

View file

@ -2163,7 +2163,7 @@ namespace {
text = d.second; text = d.second;
} }
void prepareCorners(RoundCorners index, int32 radius, const style::color &color, const style::color *shadow = 0, QImage *cors = 0) { void prepareCorners(RoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor(); int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4]; QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
{ {
@ -2178,7 +2178,7 @@ namespace {
p.setBrush((*shadow)->b); p.setBrush((*shadow)->b);
p.drawRoundedRect(0, s, r * 3, r * 3, r, r); p.drawRoundedRect(0, s, r * 3, r * 3, r, r);
} }
p.setBrush(color->b); p.setBrush(brush);
p.drawRoundedRect(0, 0, r * 3, r * 3, r, r); p.drawRoundedRect(0, 0, r * 3, r * 3, r, r);
} }
if (!cors) cors = localCors; if (!cors) cors = localCors;
@ -2212,14 +2212,13 @@ namespace {
} }
void createCorners() { void createCorners() {
style::color white = { 255, 255, 255, 255 };
QImage mask[4]; QImage mask[4];
prepareCorners(LargeMaskCorners, msgRadius(), white, nullptr, mask); prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); ::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
::cornersMaskLarge[i]->setDevicePixelRatio(cRetinaFactor()); ::cornersMaskLarge[i]->setDevicePixelRatio(cRetinaFactor());
} }
prepareCorners(SmallMaskCorners, st::buttonRadius, white, nullptr, mask); prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); ::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor()); ::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor());
@ -2295,7 +2294,7 @@ namespace {
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) { static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
if (update.type == Update::Type::TestingTheme) { if (update.paletteChanged()) {
clearCorners(); clearCorners();
createCorners(); createCorners();
@ -2770,7 +2769,7 @@ namespace {
if (radius == ImageRoundRadius::Large) { if (radius == ImageRoundRadius::Large) {
complexAdjustRect(corners, rect, overlayParts); complexAdjustRect(corners, rect, overlayParts);
} }
roundRect(p, rect, textstyleCurrent()->selectOverlay, overlayCorners, nullptr, overlayParts); roundRect(p, rect, p.textPalette().selectOverlay, overlayCorners, nullptr, overlayParts);
} }
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) { void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners) {
@ -2787,7 +2786,8 @@ namespace {
} }
return ::cornersMaskSmall; return ::cornersMaskSmall;
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor(); auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor(); auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor();
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return; if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
@ -2831,11 +2831,11 @@ namespace {
} }
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *shadow, RectParts parts) { void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) {
roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts); roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts);
} }
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &shadow, RoundCorners index, RectParts parts) { void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts) {
auto &corner = ::corners[index]; auto &corner = ::corners[index];
auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor(); auto cornerWidth = corner.p[0]->width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor(); auto cornerHeight = corner.p[0]->height() / cIntRetinaFactor();
@ -2852,7 +2852,7 @@ namespace {
} }
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, ImageRoundRadius radius, RectParts parts) { void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24); auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
auto i = cornersMap.find(colorKey); auto i = cornersMap.find(colorKey);
if (i == cornersMap.cend()) { if (i == cornersMap.cend()) {

View file

@ -307,16 +307,16 @@ namespace App {
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners); void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners);
QImage **cornersMask(ImageRoundRadius radius); QImage **cornersMask(ImageRoundRadius radius);
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full); void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, const style::color &bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) { inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts); return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
} }
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &shadow, RoundCorners index, RectParts parts = RectPart::Full); void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full);
inline void roundShadow(Painter &p, const QRect &rect, const style::color &shadow, RoundCorners index, RectParts parts = RectPart::Full) { inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) {
return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts); return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, ImageRoundRadius radius, RectParts parts = RectPart::Full); void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, const style::color &bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) { inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts); return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
} }

View file

@ -38,6 +38,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "media/player/media_player_instance.h" #include "media/player/media_player_instance.h"
#include "window/notifications_manager.h" #include "window/notifications_manager.h"
#include "history/history_location_manager.h" #include "history/history_location_manager.h"
#include "core/task_queue.h"
namespace { namespace {
@ -364,6 +365,10 @@ void Application::closeApplication() {
#endif // !TDESKTOP_DISABLE_AUTOUPDATE #endif // !TDESKTOP_DISABLE_AUTOUPDATE
} }
void Application::onMainThreadTask() {
base::TaskQueue::ProcessMainTasks();
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE #ifndef TDESKTOP_DISABLE_AUTOUPDATE
void Application::updateCheck() { void Application::updateCheck() {
startUpdateCheck(false); startUpdateCheck(false);

View file

@ -48,6 +48,8 @@ public slots:
void startApplication(); // will be done in exec() void startApplication(); // will be done in exec()
void closeApplication(); // will be done in aboutToQuit() void closeApplication(); // will be done in aboutToQuit()
void onMainThreadTask();
private: private:
typedef QPair<QLocalSocket*, QByteArray> LocalClient; typedef QPair<QLocalSocket*, QByteArray> LocalClient;
typedef QList<LocalClient> LocalClients; typedef QList<LocalClient> LocalClients;

View file

@ -34,9 +34,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
AboutBox::AboutBox(QWidget *parent) AboutBox::AboutBox(QWidget *parent)
: _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? " alpha" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), st::aboutVersionLink) : _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? " alpha" : "") + (cBetaVersion() ? qsl(" beta %1").arg(cBetaVersion()) : QString())), st::aboutVersionLink)
, _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle) , _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
, _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle) , _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
, _text3(this, st::aboutLabel, st::aboutTextStyle) { , _text3(this, st::aboutLabel) {
} }
void AboutBox::prepare() { void AboutBox::prepare() {

View file

@ -427,8 +427,8 @@ SetupChannelBox::SetupChannelBox(QWidget*, ChannelData *channel, bool existing)
, _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true, st::defaultBoxCheckbox) , _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true, st::defaultBoxCheckbox)
, _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), false, st::defaultBoxCheckbox) , _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), false, st::defaultBoxCheckbox)
, _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultBoxCheckbox.textPosition.x()) , _aboutPublicWidth(width() - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultBoxCheckbox.textPosition.x())
, _aboutPublic(st::normalFont, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth) , _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
, _aboutPrivate(st::normalFont, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth) , _aboutPrivate(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
, _link(this, st::setupChannelLink, QString(), channel->username, true) { , _link(this, st::setupChannelLink, QString(), channel->username, true) {
} }
@ -1219,9 +1219,9 @@ void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selecte
p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), lang(lng_channels_too_much_public_revoke), _revokeWidth); p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), lang(lng_channels_too_much_public_revoke), _revokeWidth);
p.setPen(st::contactsStatusFg); p.setPen(st::contactsStatusFg);
textstyleSet(&st::revokePublicLinkStatusStyle); p.setTextPalette(st::revokePublicLinkStatusPalette);
row.status.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsStatusTop, namew, width()); row.status.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsStatusTop, namew, width());
textstyleRestore(); p.restoreTextPalette();
} }
void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) { void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
@ -1232,10 +1232,8 @@ void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
ChatRow row; ChatRow row;
row.peer = peer; row.peer = peer;
row.name.setText(st::contactsNameFont, peer->name, _textNameOptions); row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
textstyleSet(&st::revokePublicLinkStatusStyle); row.status.setText(st::defaultTextStyle, qsl("telegram.me/") + textcmdLink(1, peer->userName()), _textDlgOptions);
row.status.setText(st::normalFont, qsl("telegram.me/") + textcmdLink(1, peer->userName()), _textDlgOptions);
textstyleRestore();
_rows.push_back(std_::move(row)); _rows.push_back(std_::move(row));
} }
} }

View file

@ -67,8 +67,7 @@ BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent)
subscribe(FileDownload::ImageLoaded(), [this] { update(); }); subscribe(FileDownload::ImageLoaded(), [this] { update(); });
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) { subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme if (update.paletteChanged()) {
|| update.type == Update::Type::RevertingTheme) {
_check->invalidateCache(); _check->invalidateCache();
} }
}); });

View file

@ -30,19 +30,9 @@ boxButtonFont: font(boxFontSize semibold);
defaultBoxButton: RoundButton(defaultLightButton) { defaultBoxButton: RoundButton(defaultLightButton) {
width: -24px; width: -24px;
height: 36px; height: 36px;
padding: margins(0px, 0px, 0px, 0px);
textTop: 8px;
font: boxButtonFont; font: boxButtonFont;
ripple: RippleAnimation(defaultRippleAnimation) {
color: lightButtonBgRipple;
}
} }
cancelBoxButton: defaultBoxButton;
attentionBoxButton: RoundButton(defaultBoxButton) { attentionBoxButton: RoundButton(defaultBoxButton) {
textFg: attentionButtonFg; textFg: attentionButtonFg;
textFgOver: attentionButtonFgOver; textFgOver: attentionButtonFgOver;
@ -118,8 +108,12 @@ boxMediumSkip: 20px;
boxButtonPadding: margins(8px, 12px, 13px, 12px); boxButtonPadding: margins(8px, 12px, 13px, 12px);
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px); boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
boxLabel: FlatLabel(defaultFlatLabel) { boxLabel: FlatLabel(defaultFlatLabel) {
font: font(boxFontSize);
align: align(topleft); align: align(topleft);
style: TextStyle(defaultTextStyle) {
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
} }
countryRowHeight: 36px; countryRowHeight: 36px;
@ -153,14 +147,17 @@ cropSkip: 13px;
cropMinSize: 20px; cropMinSize: 20px;
confirmInviteTitle: FlatLabel(defaultFlatLabel) { confirmInviteTitle: FlatLabel(defaultFlatLabel) {
font: font(16px semibold);
align: align(center); align: align(center);
width: 320px; width: 320px;
maxHeight: 24px; maxHeight: 24px;
textFg: windowBoldFg; textFg: windowBoldFg;
style: TextStyle(defaultTextStyle) {
font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
} }
confirmInviteStatus: FlatLabel(defaultFlatLabel) { confirmInviteStatus: FlatLabel(boxLabel) {
font: font(boxFontSize);
align: align(center); align: align(center);
width: 320px; width: 320px;
maxHeight: 20px; maxHeight: 20px;
@ -174,7 +171,6 @@ confirmInviteUserHeight: 84px;
confirmInviteUserPhotoSize: 56px; confirmInviteUserPhotoSize: 56px;
confirmInviteUserPhotoTop: 166px; confirmInviteUserPhotoTop: 166px;
confirmInviteUserName: FlatLabel(defaultFlatLabel) { confirmInviteUserName: FlatLabel(defaultFlatLabel) {
font: normalFont;
align: align(center); align: align(center);
width: 66px; width: 66px;
maxHeight: 20px; maxHeight: 20px;
@ -187,16 +183,12 @@ confirmPhoneAboutLabel: FlatLabel(defaultFlatLabel) {
confirmPhoneCodeField: InputField(defaultInputField) { confirmPhoneCodeField: InputField(defaultInputField) {
} }
revokePublicLinkStatusStyle: TextStyle(defaultTextStyle) { revokePublicLinkStatusPalette: TextPalette(defaultTextPalette) {
linkFg: contactsStatusFgOnline; linkFg: contactsStatusFgOnline;
linkFgDown: contactsStatusFgOnline;
linkFlagsOver: font(fsize);
} }
aboutRevokePublicLabel: FlatLabel(defaultFlatLabel) { aboutRevokePublicLabel: FlatLabel(defaultFlatLabel) {
font: normalFont;
align: align(topleft); align: align(topleft);
width: 320px; width: 320px;
textFg: windowFg;
} }
contactUserIcon: icon {{ "add_contact_user", menuIconFg }}; contactUserIcon: icon {{ "add_contact_user", menuIconFg }};
@ -228,7 +220,11 @@ contactPhoneSkip: 30px;
contactsPhotoSize: 42px; contactsPhotoSize: 42px;
contactsPadding: margins(16px, 7px, 16px, 7px); contactsPadding: margins(16px, 7px, 16px, 7px);
contactsNameTop: 2px; contactsNameTop: 2px;
contactsNameFont: semiboldFont; contactsNameStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: semiboldFont;
}
contactsStatusTop: 23px; contactsStatusTop: 23px;
contactsStatusFont: font(fsize); contactsStatusFont: font(fsize);
contactsCheckPosition: point(8px, 16px); contactsCheckPosition: point(8px, 16px);
@ -255,7 +251,7 @@ contactsMultiSelect: MultiSelect {
padding: margins(6px, 7px, 12px, 0px); padding: margins(6px, 7px, 12px, 0px);
maxWidth: 128px; maxWidth: 128px;
height: 32px; height: 32px;
font: normalFont; style: defaultTextStyle;
textBg: contactsBgOver; textBg: contactsBgOver;
textFg: windowFg; textFg: windowFg;
textActiveBg: activeButtonBg; textActiveBg: activeButtonBg;
@ -345,7 +341,11 @@ sharePhotoCheckbox: RoundImageCheckbox(contactsPhotoCheckbox) {
imageRadius: 28px; imageRadius: 28px;
imageSmallRadius: 24px; imageSmallRadius: 24px;
} }
shareNameFont: font(11px); shareNameStyle: TextStyle(defaultTextStyle) {
font: font(11px);
linkFont: font(11px);
linkFontOver: font(11px);
}
shareNameFg: windowFg; shareNameFg: windowFg;
shareNameActiveFg: windowActiveTextFg; shareNameActiveFg: windowActiveTextFg;
shareNameTop: 6px; shareNameTop: 6px;
@ -460,12 +460,11 @@ aboutVersionLink: LinkButton(defaultLinkButton) {
aboutTextTop: 34px; aboutTextTop: 34px;
aboutSkip: 14px; aboutSkip: 14px;
aboutLabel: FlatLabel(defaultFlatLabel) { aboutLabel: FlatLabel(defaultFlatLabel) {
font: normalFont;
width: 330px; width: 330px;
align: align(topleft); align: align(topleft);
} style: TextStyle(defaultTextStyle) {
aboutTextStyle: TextStyle(defaultTextStyle) { lineHeight: 22px;
lineHeight: 22px; }
} }
autoDownloadTopDelta: 10px; autoDownloadTopDelta: 10px;
@ -513,10 +512,16 @@ backgroundScroll: ScrollArea(boxLayerScroll) {
deltab: 10px; deltab: 10px;
} }
passcodeTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 20px;
}
usernamePadding: margins(23px, 6px, 21px, 12px); usernamePadding: margins(23px, 6px, 21px, 12px);
usernameSkip: 49px; usernameSkip: 49px;
usernameTextStyle: TextStyle(defaultTextStyle) { usernameTextStyle: TextStyle(passcodeTextStyle) {
lineHeight: 20px; font: boxTextFont;
linkFont: boxTextFont;
linkFontOver: font(boxFontSize underline);
} }
usernameDefaultFg: windowSubTextFg; usernameDefaultFg: windowSubTextFg;

View file

@ -102,18 +102,17 @@ ConfirmBox::ConfirmBox(const InformBoxTag &, const QString &text, const QString
} }
base::lambda<void()> ConfirmBox::generateInformCallback(const base::lambda_copy<void()> &closedCallback) { base::lambda<void()> ConfirmBox::generateInformCallback(const base::lambda_copy<void()> &closedCallback) {
return base::lambda_guarded(this, [this, closedCallback] { auto callback = closedCallback;
return base::lambda_guarded(this, [this, callback] {
closeBox(); closeBox();
if (closedCallback) { if (callback) {
closedCallback(); callback();
} }
}); });
} }
void ConfirmBox::init(const QString &text) { void ConfirmBox::init(const QString &text) {
textstyleSet(&st::boxTextStyle); _text.setText(st::boxTextStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
_text.setText(st::boxTextFont, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
textstyleRestore();
} }
void ConfirmBox::prepare() { void ConfirmBox::prepare() {
@ -125,11 +124,9 @@ void ConfirmBox::prepare() {
} }
void ConfirmBox::textUpdated() { void ConfirmBox::textUpdated() {
textstyleSet(&st::boxTextStyle);
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight)); _textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom()); setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
textstyleRestore();
setMouseTracking(_text.hasLinks()); setMouseTracking(_text.hasLinks());
} }
@ -192,9 +189,7 @@ void ConfirmBox::updateLink() {
void ConfirmBox::updateHover() { void ConfirmBox::updateHover() {
QPoint m(mapFromGlobal(_lastMousePos)); QPoint m(mapFromGlobal(_lastMousePos));
textstyleSet(&st::boxTextStyle);
auto state = _text.getStateLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width()); auto state = _text.getStateLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width());
textstyleRestore();
ClickHandler::setActive(state.link, this); ClickHandler::setActive(state.link, this);
} }
@ -214,9 +209,7 @@ void ConfirmBox::paintEvent(QPaintEvent *e) {
// draw box title / text // draw box title / text
p.setPen(st::boxTextFg); p.setPen(st::boxTextFg);
textstyleSet(&st::boxTextStyle);
_text.drawLeftElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, width(), 16, style::al_left); _text.drawLeftElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, width(), 16, style::al_left);
textstyleRestore();
} }
InformBox::InformBox(QWidget*, const QString &text, base::lambda_copy<void()> &&closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std_::move(closedCallback)) { InformBox::InformBox(QWidget*, const QString &text, base::lambda_copy<void()> &&closedCallback) : ConfirmBox(ConfirmBox::InformBoxTag(), text, lang(lng_box_ok), std_::move(closedCallback)) {
@ -226,7 +219,7 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, bas
} }
MaxInviteBox::MaxInviteBox(QWidget*, const QString &link) MaxInviteBox::MaxInviteBox(QWidget*, const QString &link)
: _text(st::boxTextFont, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right()) : _text(st::boxTextStyle, lng_participant_invite_sorry(lt_count, Global::ChatSizeMax()), _confirmBoxTextOptions, st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right())
, _link(link) { , _link(link) {
} }
@ -309,13 +302,11 @@ void ConvertToSupergroupBox::prepare() {
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); }); addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
textstyleSet(&st::boxTextStyle); _text.setText(st::boxTextStyle, text.join('\n'), _confirmBoxTextOptions);
_text.setText(st::boxTextFont, text.join('\n'), _confirmBoxTextOptions); _note.setText(st::boxTextStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_note.setText(st::boxTextFont, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right(); _textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = _text.countHeight(_textWidth); _textHeight = _text.countHeight(_textWidth);
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth)); setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
textstyleRestore();
} }
void ConvertToSupergroupBox::convertToSupergroup() { void ConvertToSupergroupBox::convertToSupergroup() {
@ -368,10 +359,8 @@ void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
// draw box title / text // draw box title / text
p.setPen(st::boxTextFg); p.setPen(st::boxTextFg);
textstyleSet(&st::boxTextStyle);
_text.drawLeft(p, st::boxPadding.left(), 0, _textWidth, width()); _text.drawLeft(p, st::boxPadding.left(), 0, _textWidth, width());
_note.drawLeft(p, st::boxPadding.left(), _textHeight + st::boxPadding.bottom(), _textWidth, width()); _note.drawLeft(p, st::boxPadding.left(), _textHeight + st::boxPadding.bottom(), _textWidth, width());
textstyleRestore();
} }
PinMessageBox::PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId) PinMessageBox::PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId)

View file

@ -562,8 +562,8 @@ ContactsBox::Inner::Inner(QWidget *parent, ChatData *chat, MembersFilter members
, _membersFilter(membersFilter) , _membersFilter(membersFilter)
, _allAdmins(this, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::defaultBoxCheckbox) , _allAdmins(this, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::defaultBoxCheckbox)
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right()) , _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right())
, _aboutAllAdmins(st::normalFont, lang(lng_chat_about_all_admins), _defaultOptions, _aboutWidth) , _aboutAllAdmins(st::defaultTextStyle, lang(lng_chat_about_all_admins), _defaultOptions, _aboutWidth)
, _aboutAdmins(st::normalFont, lang(lng_chat_about_admins), _defaultOptions, _aboutWidth) , _aboutAdmins(st::defaultTextStyle, lang(lng_chat_about_admins), _defaultOptions, _aboutWidth)
, _customList((membersFilter == MembersFilter::Recent) ? std_::unique_ptr<Dialogs::IndexedList>() : std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Add)) , _customList((membersFilter == MembersFilter::Recent) ? std_::unique_ptr<Dialogs::IndexedList>() : std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Add))
, _contacts((membersFilter == MembersFilter::Recent) ? App::main()->contactsList() : _customList.get()) , _contacts((membersFilter == MembersFilter::Recent) ? App::main()->contactsList() : _customList.get())
, _addContactLnk(this, lang(lng_add_contact_button)) { , _addContactLnk(this, lang(lng_add_contact_button)) {
@ -640,8 +640,7 @@ void ContactsBox::Inner::init() {
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) { subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme if (update.paletteChanged()) {
|| update.type == Update::Type::RevertingTheme) {
invalidateCache(); invalidateCache();
} }
}); });
@ -897,7 +896,7 @@ ContactsBox::Inner::ContactData *ContactsBox::Inner::contactData(Dialogs::Row *r
if (usingMultiSelect() && _checkedContacts.contains(peer)) { if (usingMultiSelect() && _checkedContacts.contains(peer)) {
data->checkbox->setChecked(true, Ui::RoundImageCheckbox::SetStyle::Fast); data->checkbox->setChecked(true, Ui::RoundImageCheckbox::SetStyle::Fast);
} }
data->name.setText(st::contactsNameFont, peer->name, _textNameOptions); data->name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
if (peer->isUser()) { if (peer->isUser()) {
data->statusText = App::onlineText(peer->asUser(), _time); data->statusText = App::onlineText(peer->asUser(), _time);
data->statusHasOnlineColor = App::onlineColorUse(peer->asUser(), _time); data->statusHasOnlineColor = App::onlineColorUse(peer->asUser(), _time);
@ -1746,7 +1745,7 @@ void ContactsBox::Inner::peopleReceived(const QString &query, const QVector<MTPP
if (usingMultiSelect() && _checkedContacts.contains(peer)) { if (usingMultiSelect() && _checkedContacts.contains(peer)) {
data->checkbox->setChecked(true, Ui::RoundImageCheckbox::SetStyle::Fast); data->checkbox->setChecked(true, Ui::RoundImageCheckbox::SetStyle::Fast);
} }
data->name.setText(st::contactsNameFont, peer->name, _textNameOptions); data->name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
data->statusText = '@' + peer->userName(); data->statusText = '@' + peer->userName();
_byUsernameFiltered.push_back(peer); _byUsernameFiltered.push_back(peer);

View file

@ -374,7 +374,7 @@ void MembersBox::Inner::refresh() {
resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom); resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom);
_aboutHeight = 0; _aboutHeight = 0;
} else { } else {
_about.setText(st::boxTextFont, lng_channel_only_last_shown(lt_count, _rows.size())); _about.setText(st::boxTextStyle, lng_channel_only_last_shown(lt_count, _rows.size()));
_aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom(); _aboutHeight = st::membersAboutLimitPadding.top() + _about.countHeight(_aboutWidth) + st::membersAboutLimitPadding.bottom();
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) { if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
_aboutHeight = 0; _aboutHeight = 0;
@ -420,7 +420,7 @@ MembersBox::Inner::MemberData *MembersBox::Inner::data(int32 index) {
return result; return result;
} }
MemberData *result = _datas[index] = new MemberData(); MemberData *result = _datas[index] = new MemberData();
result->name.setText(st::contactsNameFont, _rows[index]->name, _textNameOptions); result->name.setText(st::contactsNameStyle, _rows[index]->name, _textNameOptions);
int32 t = unixtime(); int32 t = unixtime();
result->online = App::onlineText(_rows[index], t);// lng_mediaview_date_time(lt_date, _dates[index].date().toString(qsl("dd.MM.yy")), lt_time, _dates[index].time().toString(cTimeFormat())); result->online = App::onlineText(_rows[index], t);// lng_mediaview_date_time(lt_date, _dates[index].date().toString(qsl("dd.MM.yy")), lt_time, _dates[index].time().toString(cTimeFormat()));
result->onlineColor = App::onlineColorUse(_rows[index], t); result->onlineColor = App::onlineColorUse(_rows[index], t);
@ -496,7 +496,7 @@ void MembersBox::Inner::onPeerNameChanged(PeerData *peer, const PeerData::Names
for (int32 i = 0, l = _rows.size(); i < l; ++i) { for (int32 i = 0, l = _rows.size(); i < l; ++i) {
if (_rows.at(i) == peer) { if (_rows.at(i) == peer) {
if (_datas.at(i)) { if (_datas.at(i)) {
_datas.at(i)->name.setText(st::contactsNameFont, peer->name, _textNameOptions); _datas.at(i)->name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
update(0, st::membersMarginTop + i * _rowHeight, width(), _rowHeight); update(0, st::membersMarginTop + i * _rowHeight, width(), _rowHeight);
} else { } else {
break; break;

View file

@ -53,19 +53,15 @@ PasscodeBox::PasscodeBox(QWidget*, const QByteArray &newSalt, const QByteArray &
, _passwordHint(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint)) , _passwordHint(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint))
, _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email)) , _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email))
, _recover(this, lang(lng_signin_recover)) { , _recover(this, lang(lng_signin_recover)) {
textstyleSet(&st::usernameTextStyle); if (!hint.isEmpty()) _hintText.setText(st::passcodeTextStyle, lng_signin_hint(lt_password_hint, hint));
if (!hint.isEmpty()) _hintText.setText(st::normalFont, lng_signin_hint(lt_password_hint, hint));
textstyleRestore();
} }
void PasscodeBox::prepare() { void PasscodeBox::prepare() {
addButton(lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), [this] { onSave(); }); addButton(lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), [this] { onSave(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
textstyleSet(&st::usernameTextStyle); _about.setRichText(st::passcodeTextStyle, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about));
_about.setRichText(st::normalFont, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about));
_aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5); _aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5);
textstyleRestore();
if (_turningOff) { if (_turningOff) {
_oldPasscode->show(); _oldPasscode->show();
setTitle(lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove)); setTitle(lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove));
@ -146,8 +142,6 @@ void PasscodeBox::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
textstyleSet(&st::usernameTextStyle);
int32 w = st::boxWidth - st::boxPadding.left() * 1.5; int32 w = st::boxWidth - st::boxPadding.left() * 1.5;
int32 abouty = (_passwordHint->isHidden() ? (_reenterPasscode->isHidden() ? (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : _reenterPasscode->y()) + st::passcodeSkip : _passwordHint->y() + st::passcodeLittleSkip) + _oldPasscode->height() + st::passcodePadding.bottom(); int32 abouty = (_passwordHint->isHidden() ? (_reenterPasscode->isHidden() ? (_oldPasscode->y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeTextLine : 0)) : _reenterPasscode->y()) + st::passcodeSkip : _passwordHint->y() + st::passcodeLittleSkip) + _oldPasscode->height() + st::passcodePadding.bottom();
p.setPen(st::boxTextFg); p.setPen(st::boxTextFg);
@ -171,8 +165,6 @@ void PasscodeBox::paintEvent(QPaintEvent *e) {
p.setPen(st::boxTextFgError); p.setPen(st::boxTextFgError);
p.drawText(QRect(st::boxPadding.left(), _recoverEmail->y() + _recoverEmail->height(), w, st::passcodeTextLine), _emailError, style::al_left); p.drawText(QRect(st::boxPadding.left(), _recoverEmail->y() + _recoverEmail->height(), w, st::passcodeTextLine), _emailError, style::al_left);
} }
textstyleRestore();
} }
void PasscodeBox::resizeEvent(QResizeEvent *e) { void PasscodeBox::resizeEvent(QResizeEvent *e) {

View file

@ -102,14 +102,14 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &filepath, QImage image, Comp
if (_preview.isNull()) { if (_preview.isNull()) {
if (filepath.isEmpty()) { if (filepath.isEmpty()) {
auto filename = filedialogDefaultName(qsl("image"), qsl(".png"), QString(), true); auto filename = filedialogDefaultName(qsl("image"), qsl(".png"), QString(), true);
_nameText.setText(st::semiboldFont, filename, _textNameOptions); _nameText.setText(st::semiboldTextStyle, filename, _textNameOptions);
_statusText = qsl("%1x%2").arg(_image.width()).arg(_image.height()); _statusText = qsl("%1x%2").arg(_image.width()).arg(_image.height());
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText)); _statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
_fileIsImage = true; _fileIsImage = true;
} else { } else {
auto fileinfo = QFileInfo(filepath); auto fileinfo = QFileInfo(filepath);
auto filename = fileinfo.fileName(); auto filename = fileinfo.fileName();
_nameText.setText(st::semiboldFont, filename, _textNameOptions); _nameText.setText(st::semiboldTextStyle, filename, _textNameOptions);
_statusText = formatSizeText(fileinfo.size()); _statusText = formatSizeText(fileinfo.size());
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText)); _statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
_fileIsImage = fileIsImage(filename, mimeTypeForFile(fileinfo).name()); _fileIsImage = fileIsImage(filename, mimeTypeForFile(fileinfo).name());
@ -127,7 +127,7 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstn
: _contactPhone(phone) : _contactPhone(phone)
, _contactFirstName(firstname) , _contactFirstName(firstname)
, _contactLastName(lastname) { , _contactLastName(lastname) {
_nameText.setText(st::semiboldFont, lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName), _textNameOptions); _nameText.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName), _textNameOptions);
_statusText = _contactPhone; _statusText = _contactPhone;
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText)); _statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
} }
@ -400,9 +400,9 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryItem *msg)
if (doc) { if (doc) {
if (doc->voice()) { if (doc->voice()) {
_name.setText(st::semiboldFont, lang(lng_media_audio), _textNameOptions); _name.setText(st::semiboldTextStyle, lang(lng_media_audio), _textNameOptions);
} else { } else {
_name.setText(st::semiboldFont, documentName(doc), _textNameOptions); _name.setText(st::semiboldTextStyle, documentName(doc), _textNameOptions);
} }
_status = formatSizeText(doc->size); _status = formatSizeText(doc->size);
_statusw = qMax(_name.maxWidth(), st::normalFont->width(_status)); _statusw = qMax(_name.maxWidth(), st::normalFont->width(_status));

View file

@ -298,8 +298,7 @@ ShareBox::Inner::Inner(QWidget *parent, ShareBox::FilterCallback &&filterCallbac
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) { subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme if (update.paletteChanged()) {
|| update.type == Update::Type::RevertingTheme) {
invalidateCache(); invalidateCache();
} }
}); });
@ -362,7 +361,7 @@ void ShareBox::Inner::updateChat(PeerData *peer) {
} }
void ShareBox::Inner::updateChatName(Chat *chat, PeerData *peer) { void ShareBox::Inner::updateChatName(Chat *chat, PeerData *peer) {
chat->name.setText(st::shareNameFont, peer->name, _textNameOptions); chat->name.setText(st::shareNameStyle, peer->name, _textNameOptions);
} }
void ShareBox::Inner::repaintChatAtIndex(int index) { void ShareBox::Inner::repaintChatAtIndex(int index) {
@ -600,7 +599,7 @@ void ShareBox::Inner::updateUpon(const QPoint &pos) {
auto left = _rowsLeft + qFloor(column * _rowWidthReal) + st::shareColumnSkip / 2; auto left = _rowsLeft + qFloor(column * _rowWidthReal) + st::shareColumnSkip / 2;
auto top = _rowsTop + row * _rowHeight + st::sharePhotoTop; auto top = _rowsTop + row * _rowHeight + st::sharePhotoTop;
auto xupon = (x >= left) && (x < left + (_rowWidth - st::shareColumnSkip)); auto xupon = (x >= left) && (x < left + (_rowWidth - st::shareColumnSkip));
auto yupon = (y >= top) && (y < top + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop + st::shareNameFont->height * 2); auto yupon = (y >= top) && (y < top + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop + st::shareNameStyle.font->height * 2);
auto upon = (xupon && yupon) ? (row * _columnCount + column) : -1; auto upon = (xupon && yupon) ? (row * _columnCount + column) : -1;
if (upon >= displayedChatsCount()) { if (upon >= displayedChatsCount()) {
upon = -1; upon = -1;

View file

@ -148,7 +148,7 @@ StickersBox::StickersBox(QWidget*, const Stickers::Order &archivedIds)
: _section(Section::ArchivedPart) : _section(Section::ArchivedPart)
, _archived(0, this, archivedIds) , _archived(0, this, archivedIds)
, _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top()) , _aboutWidth(st::boxWideWidth - 2 * st::stickersReorderPadding.top())
, _about(st::boxTextFont, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) { , _about(st::boxTextStyle, lang(lng_stickers_packs_archived), _defaultOptions, _aboutWidth) {
} }
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) { void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {
@ -691,7 +691,7 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
int statusx = namex; int statusx = namex;
int statusy = st::contactsPadding.top() + st::contactsStatusTop; int statusy = st::contactsPadding.top() + st::contactsStatusTop;
p.setFont(st::contactsNameFont); p.setFont(st::contactsNameStyle.font);
p.setPen(st::contactsNameFg); p.setPen(st::contactsNameFg);
p.drawTextLeft(namex, namey, width(), s->title, s->titleWidth); p.drawTextLeft(namex, namey, width(), s->title, s->titleWidth);
@ -1225,10 +1225,10 @@ int StickersBox::Inner::fillSetCount(const Stickers::Set &set) const {
QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const { QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const {
auto result = set.title; auto result = set.title;
int titleWidth = st::contactsNameFont->width(result); int titleWidth = st::contactsNameStyle.font->width(result);
if (titleWidth > maxNameWidth) { if (titleWidth > maxNameWidth) {
result = st::contactsNameFont->elided(result, maxNameWidth); result = st::contactsNameStyle.font->elided(result, maxNameWidth);
titleWidth = st::contactsNameFont->width(result); titleWidth = st::contactsNameStyle.font->width(result);
} }
if (outTitleWidth) { if (outTitleWidth) {
*outTitleWidth = titleWidth; *outTitleWidth = titleWidth;

View file

@ -49,10 +49,8 @@ void UsernameBox::prepare() {
connect(_username, SIGNAL(submitted(bool)), this, SLOT(onSave())); connect(_username, SIGNAL(submitted(bool)), this, SLOT(onSave()));
connect(_link, SIGNAL(clicked()), this, SLOT(onLinkClick())); connect(_link, SIGNAL(clicked()), this, SLOT(onLinkClick()));
textstyleSet(&st::usernameTextStyle); _about.setRichText(st::usernameTextStyle, lang(lng_username_about));
_about.setRichText(st::boxTextFont, lang(lng_username_about));
setDimensions(st::boxWidth, st::usernamePadding.top() + _username->height() + st::usernameSkip + _about.countHeight(st::boxWidth - st::usernamePadding.left()) + 3 * st::usernameTextStyle.lineHeight + st::usernamePadding.bottom()); setDimensions(st::boxWidth, st::usernamePadding.top() + _username->height() + st::usernameSkip + _about.countHeight(st::boxWidth - st::usernamePadding.left()) + 3 * st::usernameTextStyle.lineHeight + st::usernamePadding.bottom());
textstyleRestore();
_checkTimer->setSingleShot(true); _checkTimer->setSingleShot(true);
connect(_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck())); connect(_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck()));
@ -81,10 +79,8 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose)); p.drawTextLeft(st::usernamePadding.left(), _username->y() + _username->height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose));
} }
p.setPen(st::boxTextFg); p.setPen(st::boxTextFg);
textstyleSet(&st::usernameTextStyle);
int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw); int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
_about.drawLeft(p, st::usernamePadding.left(), _username->y() + _username->height() + st::usernameSkip, availw, width()); _about.drawLeft(p, st::usernamePadding.left(), _username->y() + _username->height() + st::usernameSkip, availw, width());
textstyleRestore();
int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
if (_link->isHidden()) { if (_link->isHidden()) {
@ -102,9 +98,7 @@ void UsernameBox::resizeEvent(QResizeEvent *e) {
_username->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _username->height()); _username->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _username->height());
_username->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top()); _username->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top());
textstyleSet(&st::usernameTextStyle);
int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw); int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
textstyleRestore();
int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2); int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
_link->moveToLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2)); _link->moveToLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2));
} }

View file

@ -326,13 +326,7 @@ QString Generator::typeToDefaultValue(structure::Type type) const {
QString Generator::valueAssignmentCode(structure::Value value) const { QString Generator::valueAssignmentCode(structure::Value value) const {
auto copy = value.copyOf(); auto copy = value.copyOf();
if (!copy.isEmpty()) { if (!copy.isEmpty()) {
auto result = "st::" + copy.back(); return "st::" + copy.back();
// Copy is disabled for colors.
if (value.type().tag == Tag::Color || value.type().tag == Tag::Struct) {
result += ".clone()";
}
return result;
} }
switch (value.type().tag) { switch (value.type().tag) {
@ -343,7 +337,14 @@ QString Generator::valueAssignmentCode(structure::Value value) const {
case Tag::String: return QString("qsl(%1)").arg(stringToEncodedString(value.String())); case Tag::String: return QString("qsl(%1)").arg(stringToEncodedString(value.String()));
case Tag::Color: { case Tag::Color: {
auto v(value.Color()); auto v(value.Color());
return QString("{ %1, %2, %3, %4 }").arg(v.red).arg(v.green).arg(v.blue).arg(v.alpha); if (v.red == v.green && v.red == v.blue && v.red == 0 && v.alpha == 255) {
return QString("st::windowFg");
} else if (v.red == v.green && v.red == v.blue && v.red == 255 && v.alpha == 0) {
return QString("st::transparent");
} else {
common::logError(common::kErrorInternal, "") << "bad color value";
return QString();
}
} break; } break;
case Tag::Point: { case Tag::Point: {
auto v(value.Point()); auto v(value.Point());
@ -449,9 +450,13 @@ public:\n\
\n\ \n\
// Created not inited, should be finalized before usage.\n\ // Created not inited, should be finalized before usage.\n\
void finalize();\n\ void finalize();\n\
\n"; \n\
int indexOfColor(color c) const;\n\
color colorAtIndex(int index) const;\n\
\n\
inline const color &get_transparent() const { return _colors[0]; }; // special color\n";
int indexInPalette = 0; int indexInPalette = 1;
if (!module_.enumVariables([this, &indexInPalette](const Variable &variable) -> bool { if (!module_.enumVariables([this, &indexInPalette](const Variable &variable) -> bool {
auto name = variable.name.back(); auto name = variable.name.back();
if (variable.value.type().tag != structure::TypeTag::Color) { if (variable.value.type().tag != structure::TypeTag::Color) {
@ -459,7 +464,7 @@ public:\n\
} }
auto index = (indexInPalette++); auto index = (indexInPalette++);
header_->stream() << "\tinline const color &" << name << "() const { return _colors[" << index << "]; };\n"; header_->stream() << "\tinline const color &get_" << name << "() const { return _colors[" << index << "]; };\n";
return true; return true;
})) return false; })) return false;
@ -468,7 +473,7 @@ public:\n\
\n\ \n\
palette &operator=(const palette &other) {\n\ palette &operator=(const palette &other) {\n\
auto wasReady = _ready;\n\ auto wasReady = _ready;\n\
for (int i = 0; i != " << count << "; ++i) {\n\ for (int i = 0; i != kCount; ++i) {\n\
if (other._status[i] == Status::Loaded) {\n\ if (other._status[i] == Status::Loaded) {\n\
if (_status[i] == Status::Initial) {\n\ if (_status[i] == Status::Initial) {\n\
new (data(i)) internal::ColorData(*other.data(i));\n\ new (data(i)) internal::ColorData(*other.data(i));\n\
@ -494,8 +499,10 @@ public:\n\
}\n\ }\n\
\n\ \n\
private:\n\ private:\n\
static constexpr auto kCount = " << count << ";\n\
\n\
void clear() {\n\ void clear() {\n\
for (int i = 0; i != " << count << "; ++i) {\n\ for (int i = 0; i != kCount; ++i) {\n\
if (_status[i] != Status::Initial) {\n\ if (_status[i] != Status::Initial) {\n\
data(i)->~ColorData();\n\ data(i)->~ColorData();\n\
_status[i] = Status::Initial;\n\ _status[i] = Status::Initial;\n\
@ -540,15 +547,15 @@ private:\n\
Loaded,\n\ Loaded,\n\
};\n\ };\n\
\n\ \n\
alignas(alignof(internal::ColorData)) char _data[sizeof(internal::ColorData) * " << count << "];\n\ alignas(alignof(internal::ColorData)) char _data[sizeof(internal::ColorData) * kCount];\n\
\n\ \n\
color _colors[" << count << "] = {\n"; color _colors[kCount] = {\n";
for (int i = 0; i != count; ++i) { for (int i = 0; i != count; ++i) {
header_->stream() << "\t\tdata(" << i << "),\n"; header_->stream() << "\t\tdata(" << i << "),\n";
} }
header_->stream() << "\ header_->stream() << "\
};\n\ };\n\
Status _status[" << count << "] = { Status::Initial };\n\ Status _status[kCount] = { Status::Initial };\n\
bool _ready = false;\n\ bool _ready = false;\n\
\n\ \n\
};\n\ };\n\
@ -561,11 +568,10 @@ bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a);\n\
bool setColor(QLatin1String name, QLatin1String from);\n\ bool setColor(QLatin1String name, QLatin1String from);\n\
void apply(const palette &other);\n\ void apply(const palette &other);\n\
void reset();\n\ void reset();\n\
int indexOfColor(color c);\n\
\n\ \n\
} // namespace main_palette\n"; } // namespace main_palette\n";
header_->newline();
return true; return true;
} }
@ -601,21 +607,8 @@ bool Generator::writeStructsDefinitions() {
} }
bool result = module_.enumStructs([this](const Struct &value) -> bool { bool result = module_.enumStructs([this](const Struct &value) -> bool {
QStringList fields;
for (auto field : value.fields) {
auto clone = field.name.back();
if (field.type.tag == Tag::Color || field.type.tag == Tag::Struct) {
clone += ".clone()";
}
fields.push_back(clone);
}
header_->stream() << "\ header_->stream() << "\
struct " << value.name.back() << " {\n\ struct " << value.name.back() << " {\n";
" << value.name.back() << " clone() const {\n\
return { " << fields.join(", ") << " };\n\
}\n";
if (!fields.empty()) header_->newline();
for (auto &field : value.fields) { for (auto &field : value.fields) {
auto type = typeToString(field.type); auto type = typeToString(field.type);
if (type.isEmpty()) { if (type.isEmpty()) {
@ -638,6 +631,9 @@ bool Generator::writeRefsDeclarations() {
header_->pushNamespace("st"); header_->pushNamespace("st");
if (isPalette_) {
header_->stream() << "extern const style::color &transparent; // special color\n";
}
bool result = module_.enumVariables([this](const Variable &value) -> bool { bool result = module_.enumVariables([this](const Variable &value) -> bool {
auto name = value.name.back(); auto name = value.name.back();
auto type = typeToString(value.value.type()); auto type = typeToString(value.value.type());
@ -699,6 +695,9 @@ bool Generator::writeRefsDefinition() {
return true; return true;
} }
if (isPalette_) {
source_->stream() << "const style::color &transparent(_palette.get_transparent()); // special color\n";
}
bool result = module_.enumVariables([this](const Variable &variable) -> bool { bool result = module_.enumVariables([this](const Variable &variable) -> bool {
auto name = variable.name.back(); auto name = variable.name.back();
auto type = typeToString(variable.value.type()); auto type = typeToString(variable.value.type());
@ -707,7 +706,7 @@ bool Generator::writeRefsDefinition() {
} }
source_->stream() << "const " << type << " &" << name << "("; source_->stream() << "const " << type << " &" << name << "(";
if (isPalette_) { if (isPalette_) {
source_->stream() << "_palette." << name << "()"; source_->stream() << "_palette.get_" << name << "()";
} else { } else {
source_->stream() << "_" << name; source_->stream() << "_" << name;
} }
@ -719,13 +718,30 @@ bool Generator::writeRefsDefinition() {
bool Generator::writeSetPaletteColor() { bool Generator::writeSetPaletteColor() {
source_->newline(); source_->newline();
source_->stream() << "\ source_->stream() << "\n\
int palette::indexOfColor(style::color c) const {\n\
auto start = data(0);\n\
if (c._data >= start && c._data < start + kCount) {\n\
return static_cast<int>(c._data - start);\n\
}\n\
return -1;\n\
}\n\
\n\
color palette::colorAtIndex(int index) const {\n\
t_assert(_ready);\n\
t_assert(index >= 0 && index < kCount);\n\
return _colors[index];\n\
}\n\
\n\
void palette::finalize() {\n\ void palette::finalize() {\n\
if (_ready) return;\n\ if (_ready) return;\n\
_ready = true;\n\n"; _ready = true;\n\
\n\
compute(0, -1, { 255, 255, 255, 0}); // special color\n";
int indexInPalette = 0; int indexInPalette = 1;
QByteArray checksumString; QByteArray checksumString;
checksumString.append("&transparent:{ 255, 255, 255, 0 }");
bool result = module_.enumVariables([this, &indexInPalette, &checksumString](const Variable &variable) -> bool { bool result = module_.enumVariables([this, &indexInPalette, &checksumString](const Variable &variable) -> bool {
auto name = variable.name.back(); auto name = variable.name.back();
auto index = indexInPalette++; auto index = indexInPalette++;
@ -735,8 +751,9 @@ void palette::finalize() {\n\
} }
auto color = variable.value.Color(); auto color = variable.value.Color();
auto fallbackIndex = paletteIndices_.value(colorFallbackName(variable.value), -1); auto fallbackIndex = paletteIndices_.value(colorFallbackName(variable.value), -1);
source_->stream() << "\tcompute(" << index << ", " << fallbackIndex << ", {" << color.red << ", " << color.green << ", " << color.blue << ", " << color.alpha << "});\n"; auto assignment = QString("{ %1, %2, %3, %4 }").arg(color.red).arg(color.green).arg(color.blue).arg(color.alpha);
checksumString.append('&' + name + ':' + valueAssignmentCode(variable.value)); source_->stream() << "\tcompute(" << index << ", " << fallbackIndex << ", " << assignment << ");\n";
checksumString.append('&' + name + ':' + assignment);
return true; return true;
}); });
auto count = indexInPalette; auto count = indexInPalette;
@ -888,6 +905,10 @@ void reset() {\n\
style::internal::resetIcons();\n\ style::internal::resetIcons();\n\
}\n\ }\n\
\n\ \n\
int indexOfColor(color c) {\n\
return _palette.indexOfColor(c);\n\
}\n\
\n\
} // namespace main_palette\n\ } // namespace main_palette\n\
\n"; \n";
@ -1226,8 +1247,12 @@ bool Generator::writeSampleTheme(const QString &filepath) {
return false; return false;
} }
auto color = variable.value.Color(); auto color = variable.value.Color();
auto colorString = paletteColorValue(color); //color.red = uchar(rand() % 256);
//color.green = uchar(rand() % 256);
//color.blue = uchar(rand() % 256);
//auto fallbackIndex = -1;
auto fallbackIndex = paletteIndices_.value(colorFallbackName(variable.value), -1); auto fallbackIndex = paletteIndices_.value(colorFallbackName(variable.value), -1);
auto colorString = paletteColorValue(color);
if (fallbackIndex >= 0) { if (fallbackIndex >= 0) {
auto fallbackVariable = module_.findVariableInModule(names[fallbackIndex], module_); auto fallbackVariable = module_.findVariableInModule(names[fallbackIndex], module_);
if (!fallbackVariable || fallbackVariable->value.type().tag != structure::TypeTag::Color) { if (!fallbackVariable || fallbackVariable->value.type().tag != structure::TypeTag::Color) {

View file

@ -94,47 +94,43 @@ namespace internal {
template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_move_impl; template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_move_impl;
// template <typename Lambda, typename Return, typename ...Args>
// Disable large lambda support. struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
// If you really need it, just store data in some std_::unique_ptr<struct>. using JustLambda = std_::decay_simple_t<Lambda>;
// using LambdaPtr = std_::unique_ptr<JustLambda>;
//template <typename Lambda, typename Return, typename ...Args> using Parent = lambda_wrap_helper_base<Return, Args...>;
//struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> { static void construct_move_other_method(void *lambda, void *source) {
// using JustLambda = std_::decay_simple_t<Lambda>; auto source_lambda = static_cast<LambdaPtr*>(source);
// using LambdaPtr = std_::unique_ptr<JustLambda>; new (lambda) LambdaPtr(std_::move(*source_lambda));
// using Parent = lambda_wrap_helper_base<Return, Args...>; }
// static void construct_move_other_method(void *lambda, void *source) { static void construct_move_lambda_method(void *lambda, void *source) {
// auto source_lambda = static_cast<LambdaPtr*>(source); auto source_lambda = static_cast<JustLambda*>(source);
// new (lambda) LambdaPtr(std_::move(*source_lambda)); new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
// } }
// static void construct_move_lambda_method(void *lambda, void *source) { static Return call_method(const void *lambda, Args... args) {
// auto source_lambda = static_cast<JustLambda*>(source); return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...);
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda))); }
// } static void destruct_method(const void *lambda) {
// static Return call_method(const void *lambda, Args... args) { static_cast<const LambdaPtr*>(lambda)->~LambdaPtr();
// return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...); }
// } lambda_wrap_helper_move_impl() : Parent(
// static void destruct_method(const void *lambda) { &Parent::bad_construct_copy,
// static_cast<const LambdaPtr*>(lambda)->~LambdaPtr(); &lambda_wrap_helper_move_impl::construct_move_other_method,
// } &lambda_wrap_helper_move_impl::call_method,
// lambda_wrap_helper_move_impl() : Parent( &lambda_wrap_helper_move_impl::destruct_method) {
// &Parent::bad_construct_copy, }
// &lambda_wrap_helper_move_impl::construct_move_other_method,
// &lambda_wrap_helper_move_impl::call_method, protected:
// &lambda_wrap_helper_move_impl::destruct_method) { lambda_wrap_helper_move_impl(
// } typename Parent::construct_copy_other_type construct_copy_other
// ) : Parent(
//protected: construct_copy_other,
// lambda_wrap_helper_move_impl( &lambda_wrap_helper_move_impl::construct_move_other_method,
// typename Parent::construct_copy_other_type construct_copy_other &lambda_wrap_helper_move_impl::call_method,
// ) : Parent( &lambda_wrap_helper_move_impl::destruct_method) {
// construct_copy_other, }
// &lambda_wrap_helper_move_impl::construct_move_other_method,
// &lambda_wrap_helper_move_impl::call_method, };
// &lambda_wrap_helper_move_impl::destruct_method) {
// }
//
//};
template <typename Lambda, typename Return, typename ...Args> template <typename Lambda, typename Return, typename ...Args>
struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> { struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
@ -189,27 +185,23 @@ namespace internal {
template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_copy_impl; template <typename Lambda, typename IsLarge, typename Return, typename ...Args> struct lambda_wrap_helper_copy_impl;
// template <typename Lambda, typename Return, typename ...Args>
// Disable large lambda support. struct lambda_wrap_helper_copy_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> {
// If you really need it, just store data in some QSharedPointer<struct>. using JustLambda = std_::decay_simple_t<Lambda>;
// using LambdaPtr = std_::unique_ptr<JustLambda>;
//template <typename Lambda, typename Return, typename ...Args> using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>;
//struct lambda_wrap_helper_copy_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> { static void construct_copy_other_method(void *lambda, const void *source) {
// using JustLambda = std_::decay_simple_t<Lambda>; auto source_lambda = static_cast<const LambdaPtr*>(source);
// using LambdaPtr = std_::unique_ptr<JustLambda>; new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get()));
// using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>; }
// static void construct_copy_other_method(void *lambda, const void *source) { static void construct_copy_lambda_method(void *lambda, const void *source) {
// auto source_lambda = static_cast<const LambdaPtr*>(source); auto source_lambda = static_cast<const JustLambda*>(source);
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get())); new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<const JustLambda &>(*source_lambda)));
// } }
// static void construct_copy_lambda_method(void *lambda, const void *source) { lambda_wrap_helper_copy_impl() : Parent(&lambda_wrap_helper_copy_impl::construct_copy_other_method) {
// auto source_lambda = static_cast<const JustLambda*>(source); }
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<const JustLambda &>(*source_lambda)));
// } };
// lambda_wrap_helper_copy_impl() : Parent(&lambda_wrap_helper_copy_impl::construct_copy_other_method) {
// }
//
//};
template <typename Lambda, typename Return, typename ...Args> template <typename Lambda, typename Return, typename ...Args>
struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> { struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> {
@ -399,6 +391,13 @@ struct lambda_type_resolver;
template <typename Lambda, typename R, typename ...Args> template <typename Lambda, typename R, typename ...Args>
struct lambda_type_resolver<R(Lambda::*)(Args...) const> { struct lambda_type_resolver<R(Lambda::*)(Args...) const> {
using type = lambda<R(Args...)>; using type = lambda<R(Args...)>;
static constexpr auto is_mutable = false;
};
template <typename Lambda, typename R, typename ...Args>
struct lambda_type_resolver<R(Lambda::*)(Args...)> {
using type = lambda<R(Args...)>;
static constexpr auto is_mutable = true;
}; };
template <typename FunctionType> template <typename FunctionType>

View file

@ -0,0 +1,415 @@
/*
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 "core/task_queue.h"
namespace base {
namespace {
auto MainThreadId = QThread::currentThreadId();
const auto MaxThreadsCount = qMax(QThread::idealThreadCount(), 2);
template <typename Lambda>
class Thread : public QThread {
public:
Thread(Lambda code) : _code(std_::move(code)) {
}
void run() override {
_code();
}
private:
Lambda _code;
};
template <typename Lambda>
object_ptr<Thread<Lambda>> MakeThread(Lambda code) {
return object_ptr<Thread<Lambda>>(std_::move(code));
}
} // namespace
class TaskQueue::TaskQueueList {
public:
TaskQueueList();
void Register(TaskQueue *queue);
void Unregister(TaskQueue *queue);
bool IsInList(TaskQueue *queue) const;
void Clear();
bool Empty(int list_index_) const;
TaskQueue *TakeFirst(int list_index_);
private:
void Insert(TaskQueue *queue, int list_index_);
void Remove(TaskQueue *queue, int list_index_);
TaskQueue *Tail() { return &tail_; }
const TaskQueue *Tail() const { return &tail_; }
TaskQueue tail_ = { Type::Special, Priority::Normal };
TaskQueue *(lists_[kQueuesListsCount]);
};
class TaskQueue::TaskThreadPool {
struct Private {
};
public:
TaskThreadPool(const Private &) { }
static const QSharedPointer<TaskThreadPool> &Instance();
void AddQueueTask(TaskQueue *queue, Task &&task);
void RemoveQueue(TaskQueue *queue);
~TaskThreadPool();
private:
void ThreadFunction();
std_::vector_of_moveable<object_ptr<QThread>> threads_;
QMutex queues_mutex_;
// queues_mutex_ must be locked when working with the list.
TaskQueueList queue_list_;
QWaitCondition thread_condition_;
bool stopped_ = false;
int tasks_in_process_ = 0;
int background_tasks_in_process_ = 0;
};
TaskQueue::TaskQueueList::TaskQueueList() {
for (auto &list : lists_) {
list = &tail_;
}
}
void TaskQueue::TaskQueueList::Register(TaskQueue *queue) {
t_assert(!queue->SerialTaskInProcess());
Insert(queue, kAllQueuesList);
if (queue->priority_ == Priority::Normal) {
Insert(queue, kOnlyNormalQueuesList);
}
}
void TaskQueue::TaskQueueList::Unregister(TaskQueue *queue) {
Remove(queue, kAllQueuesList);
if (queue->priority_ == Priority::Normal) {
Remove(queue, kOnlyNormalQueuesList);
}
}
void TaskQueue::TaskQueueList::Insert(TaskQueue *queue, int list_index_) {
t_assert(list_index_ < kQueuesListsCount);
auto tail = Tail();
if (lists_[list_index_] == tail) {
lists_[list_index_] = queue;
}
auto &list_entry = queue->list_entries_[list_index_];
t_assert(list_entry.after == nullptr);
if ((list_entry.before = tail->list_entries_[list_index_].before)) {
list_entry.before->list_entries_[list_index_].after = queue;
}
list_entry.after = tail;
tail->list_entries_[list_index_].before = queue;
}
void TaskQueue::TaskQueueList::Remove(TaskQueue *queue, int list_index_) {
t_assert(list_index_ < kQueuesListsCount);
auto &list_entry = queue->list_entries_[list_index_];
t_assert(list_entry.after != nullptr);
if (lists_[list_index_] == queue) {
lists_[list_index_] = list_entry.after;
} else {
t_assert(list_entry.before != nullptr);
list_entry.before->list_entries_[list_index_].after = list_entry.after;
}
list_entry.after->list_entries_[list_index_].before = list_entry.before;
list_entry.before = list_entry.after = nullptr;
}
bool TaskQueue::TaskQueueList::IsInList(TaskQueue *queue) const {
if (queue->list_entries_[kAllQueuesList].after) {
return true;
}
t_assert(queue->list_entries_[kOnlyNormalQueuesList].after == nullptr);
return false;
}
void TaskQueue::TaskQueueList::Clear() {
auto tail = Tail();
for (int i = 0; i < kQueuesListsCount; ++i) {
for (auto j = lists_[i], next = j; j != tail; j = next) {
auto &list_entry = j->list_entries_[i];
next = list_entry.after;
list_entry.before = list_entry.after = nullptr;
}
lists_[i] = tail;
}
}
bool TaskQueue::TaskQueueList::Empty(int list_index_) const {
t_assert(list_index_ < kQueuesListsCount);
auto list = lists_[list_index_];
t_assert(list != nullptr);
return (list->list_entries_[list_index_].after == nullptr);
}
TaskQueue *TaskQueue::TaskQueueList::TakeFirst(int list_index_) {
t_assert(!Empty(list_index_));
auto queue = lists_[list_index_];
Unregister(queue);
// log_msgs.push_back("Unregistered from list in TakeFirst");
return queue;
}
void TaskQueue::TaskThreadPool::AddQueueTask(TaskQueue *queue, Task &&task) {
QMutexLocker lock(&queues_mutex_);
queue->tasks_.push_back(new Task(std::move(task)));
auto list_was_empty = queue_list_.Empty(kAllQueuesList);
auto threads_count = threads_.size();
auto all_threads_processing = (threads_count == tasks_in_process_);
auto some_threads_are_vacant = !all_threads_processing && list_was_empty;
auto will_create_thread = !some_threads_are_vacant && (threads_count < MaxThreadsCount);
if (!queue->SerialTaskInProcess()) {
if (!queue_list_.IsInList(queue)) {
queue_list_.Register(queue);
}
}
if (will_create_thread) {
threads_.push_back(MakeThread([this]() {
ThreadFunction();
}));
threads_.back()->start();
} else if (some_threads_are_vacant) {
t_assert(threads_count > tasks_in_process_);
thread_condition_.wakeOne();
}
}
void TaskQueue::TaskThreadPool::RemoveQueue(TaskQueue *queue) {
QMutexLocker lock(&queues_mutex_);
if (queue_list_.IsInList(queue)) {
queue_list_.Unregister(queue);
}
if (queue->destroyed_flag_) {
*queue->destroyed_flag_ = true;
}
}
TaskQueue::TaskThreadPool::~TaskThreadPool() {
{
QMutexLocker lock(&queues_mutex_);
queue_list_.Clear();
stopped_ = true;
}
thread_condition_.wakeAll();
for (auto &thread : threads_) {
thread->wait();
}
}
const QSharedPointer<TaskQueue::TaskThreadPool> &TaskQueue::TaskThreadPool::Instance() { // static
static auto Pool = MakeShared<TaskThreadPool>(Private());
return Pool;
}
void TaskQueue::TaskThreadPool::ThreadFunction() {
// Flag marking that the previous processed task was
// with a Background priority. We count all the background
// tasks being processed.
bool background_task = false;
// Saved serial queue pointer. When we process a serial
// queue task we don't return the queue to the list until
// the task is processed and we return it on the next cycle.
TaskQueue *serial_queue = nullptr;
bool serial_queue_destroyed = false;
bool task_was_processed = false;
while (true) {
std_::unique_ptr<Task> task;
{
QMutexLocker lock(&queues_mutex_);
// Finish the previous task processing.
if (task_was_processed) {
--tasks_in_process_;
}
if (background_task) {
--background_tasks_in_process_;
background_task = false;
}
if (serial_queue) {
if (!serial_queue_destroyed) {
serial_queue->destroyed_flag_ = nullptr;
if (!serial_queue->tasks_.empty()) {
queue_list_.Register(serial_queue);
}
}
serial_queue = nullptr;
serial_queue_destroyed = false;
}
// Wait for a task to appear in the queues list.
while (queue_list_.Empty(kAllQueuesList)) {
if (stopped_) {
return;
}
thread_condition_.wait(&queues_mutex_);
}
// Select a task we will be processing.
auto processing_background = (background_tasks_in_process_ > 0);
auto take_only_normal = processing_background && !queue_list_.Empty(kOnlyNormalQueuesList);
auto take_from_list_ = take_only_normal ? kOnlyNormalQueuesList : kAllQueuesList;
auto queue = queue_list_.TakeFirst(take_from_list_);
t_assert(!queue->tasks_.empty());
task.reset(queue->tasks_.front());
queue->tasks_.pop_front();
if (queue->type_ == Type::Serial) {
// Serial queues are returned in the list for processing
// only after the task is finished.
serial_queue = queue;
t_assert(serial_queue->destroyed_flag_ == nullptr);
serial_queue->destroyed_flag_ = &serial_queue_destroyed;
} else if (!queue->tasks_.empty()) {
queue_list_.Register(queue);
}
++tasks_in_process_;
task_was_processed = true;
if (queue->priority_ == Priority::Background) {
++background_tasks_in_process_;
background_task = true;
}
}
(*task)();
}
}
TaskQueue::TaskQueue(Type type, Priority priority)
: type_(type)
, priority_(priority) {
if (type_ != Type::Main && type_ != Type::Special) {
weak_thread_pool_ = TaskThreadPool::Instance();
}
}
TaskQueue::~TaskQueue() {
if (type_ != Type::Main && type_ != Type::Special) {
if (auto thread_pool = weak_thread_pool_.lock()) {
thread_pool->RemoveQueue(this);
}
}
for (auto task : take(tasks_)) {
delete task;
}
}
void TaskQueue::Put(Task &&task) {
if (type_ == Type::Main) {
QMutexLocker lock(&tasks_mutex_);
tasks_.push_back(new Task(std::move(task)));
Sandbox::MainThreadTaskAdded();
} else {
t_assert(type_ != Type::Special);
TaskThreadPool::Instance()->AddQueueTask(this, std::move(task));
}
}
void TaskQueue::ProcessMainTasks() { // static
t_assert(QThread::currentThreadId() == MainThreadId);
while (ProcessOneMainTask()) {
}
}
void TaskQueue::ProcessMainTasks(TimeMs max_time_spent) { // static
t_assert(QThread::currentThreadId() == MainThreadId);
auto start_time = getms();
while (ProcessOneMainTask()) {
if (getms() >= start_time + max_time_spent) {
break;
}
}
}
bool TaskQueue::ProcessOneMainTask() { // static
std_::unique_ptr<Task> task;
{
QMutexLocker lock(&Main().tasks_mutex_);
auto &tasks = Main().tasks_;
if (tasks.empty()) {
return false;
}
task.reset(tasks.front());
tasks.pop_front();
}
(*task)();
return true;
}
bool TaskQueue::IsMyThread() const {
if (type_ == Type::Main) {
return (QThread::currentThreadId() == MainThreadId);
}
t_assert(type_ != Type::Special);
return false;
}
// Default queues.
TaskQueue &TaskQueue::Main() { // static
static TaskQueue MainQueue { Type::Main, Priority::Normal };
return MainQueue;
}
TaskQueue &TaskQueue::Normal() { // static
static TaskQueue NormalQueue { Type::Concurrent, Priority::Normal };
return NormalQueue;
}
TaskQueue &TaskQueue::Background() { // static
static TaskQueue BackgroundQueue { Type::Concurrent, Priority::Background };
return BackgroundQueue;
}
} // namespace base

View file

@ -0,0 +1,100 @@
/*
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
*/
#pragma once
namespace base {
using Task = lambda<void()>;
// An attempt to create/use a TaskQueue or one of the default queues
// after the main() has returned leads to an undefined behaviour.
class TaskQueue {
enum class Type {
Main, // Unique queue for main thread tasks.
Serial,
Concurrent,
Special, // Unique special queue for thread pool lists terminal item.
};
public:
enum class Priority {
Normal,
Background,
};
// Creating custom serial queues.
TaskQueue(Priority priority) : TaskQueue(Type::Serial, priority) {
}
// Default main and two concurrent queues.
static TaskQueue &Main();
static TaskQueue &Normal();
static TaskQueue &Background();
void Put(Task &&task);
static void ProcessMainTasks();
static void ProcessMainTasks(TimeMs max_time_spent);
~TaskQueue();
private:
static bool ProcessOneMainTask();
TaskQueue(Type type, Priority priority);
bool IsMyThread() const;
bool SerialTaskInProcess() const {
return (destroyed_flag_ != nullptr);
}
const Type type_;
const Priority priority_;
QList<Task*> tasks_; // TODO: std_::deque_of_moveable<Task>
QMutex tasks_mutex_; // Only for the main queue.
// Only for the other queues, not main.
class TaskThreadPool;
QWeakPointer<TaskThreadPool> weak_thread_pool_;
class TaskQueueList;
struct TaskQueueListEntry {
TaskQueue *before = nullptr;
TaskQueue *after = nullptr;
};
// Thread pool queues linked list.
static constexpr int kAllQueuesList = 0;
// Thread pool queues linked list with excluded Background queues.
static constexpr int kOnlyNormalQueuesList = 1;
static constexpr int kQueuesListsCount = 2;
TaskQueueListEntry list_entries_[kQueuesListsCount];
// Only for Serial queues: non-null value means a task is currently processed.
bool *destroyed_flag_ = nullptr;
};
} // namespace base

View file

@ -19,7 +19,6 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
using "basic.style"; using "basic.style";
using "basic_types.style";
using "ui/widgets/widgets.style"; using "ui/widgets/widgets.style";
@ -32,6 +31,11 @@ dialogsRippleBg: windowBgRipple;
dialogsRippleBgActive: activeButtonBgRipple; dialogsRippleBgActive: activeButtonBgRipple;
dialogsTextFont: font(fsize); dialogsTextFont: font(fsize);
dialogsTextStyle: TextStyle(defaultTextStyle) {
font: dialogsTextFont;
linkFont: dialogsTextFont;
linkFontOver: dialogsTextFont;
}
dialogsDateFont: font(13px); dialogsDateFont: font(13px);
dialogsDateSkip: 5px; dialogsDateSkip: 5px;
dialogsNameTop: 2px; dialogsNameTop: 2px;
@ -55,30 +59,23 @@ dialogsScroll: ScrollArea(defaultScrollArea) {
bottomsh: 0px; bottomsh: 0px;
} }
dialogsTextStyle: TextStyle(defaultTextStyle) { dialogsTextPalette: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgService; linkFg: dialogsTextFgService;
linkFgDown: dialogsTextFgService;
linkFlagsOver: font(fsize);
} }
dialogsTextStyleOver: TextStyle(dialogsTextStyle) { dialogsTextPaletteOver: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgServiceOver; linkFg: dialogsTextFgServiceOver;
linkFgDown: dialogsTextFgServiceOver;
} }
dialogsTextStyleActive: TextStyle(dialogsTextStyle) { dialogsTextPaletteActive: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgServiceActive; linkFg: dialogsTextFgServiceActive;
linkFgDown: dialogsTextFgServiceActive;
} }
dialogsTextStyleDraft: TextStyle(dialogsTextStyle) { dialogsTextPaletteDraft: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFg; linkFg: dialogsDraftFg;
linkFgDown: dialogsDraftFg;
} }
dialogsTextStyleDraftOver: TextStyle(dialogsTextStyle) { dialogsTextPaletteDraftOver: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFgOver; linkFg: dialogsDraftFgOver;
linkFgDown: dialogsDraftFgOver;
} }
dialogsTextStyleDraftActive: TextStyle(dialogsTextStyle) { dialogsTextPaletteDraftActive: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFgActive; linkFg: dialogsDraftFgActive;
linkFgDown: dialogsDraftFgActive;
} }
dialogsMenuToggle: IconButton { dialogsMenuToggle: IconButton {

View file

@ -87,12 +87,12 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i
if (history->cloudDraftTextCache.isEmpty()) { if (history->cloudDraftTextCache.isEmpty()) {
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft))); auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text)); auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
history->cloudDraftTextCache.setText(st::dialogsTextFont, draftText, _textDlgOptions); history->cloudDraftTextCache.setText(st::dialogsTextStyle, draftText, _textDlgOptions);
} }
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg)); p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
textstyleSet(&(active ? st::dialogsTextStyleDraftActive : (selected ? st::dialogsTextStyleDraftOver : st::dialogsTextStyleDraft))); p.setTextPalette(active ? st::dialogsTextPaletteDraftActive : (selected ? st::dialogsTextPaletteDraftOver : st::dialogsTextPaletteDraft));
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1); history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);
textstyleRestore(); p.restoreTextPalette();
} }
} else if (!item) { } else if (!item) {
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService); auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
@ -127,7 +127,7 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth); sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
} }
if (history->peer->isUser() && history->peer->isVerified()) { if (history->peer->isVerified()) {
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon)); auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
rectForName.setWidth(rectForName.width() - icon->width()); rectForName.setWidth(rectForName.width() - icon->width());
icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), fullWidth); icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), fullWidth);
@ -144,13 +144,13 @@ struct UnreadBadgeSizeData {
class UnreadBadgeStyleData : public Data::AbstractStructure { class UnreadBadgeStyleData : public Data::AbstractStructure {
public: public:
UnreadBadgeSizeData sizes[UnreadBadgeSizesCount]; UnreadBadgeSizeData sizes[UnreadBadgeSizesCount];
const style::color *bg[6] = { style::color bg[6] = {
&st::dialogsUnreadBg, st::dialogsUnreadBg,
&st::dialogsUnreadBgOver, st::dialogsUnreadBgOver,
&st::dialogsUnreadBgActive, st::dialogsUnreadBgActive,
&st::dialogsUnreadBgMuted, st::dialogsUnreadBgMuted,
&st::dialogsUnreadBgMutedOver, st::dialogsUnreadBgMutedOver,
&st::dialogsUnreadBgMutedActive st::dialogsUnreadBgMutedActive
}; };
}; };
Data::GlobalStructurePointer<UnreadBadgeStyleData> unreadBadgeStyle; Data::GlobalStructurePointer<UnreadBadgeStyleData> unreadBadgeStyle;
@ -161,7 +161,7 @@ void createCircleMask(UnreadBadgeSizeData *data, int size) {
data->circle = style::createCircleMask(size); data->circle = style::createCircleMask(size);
} }
QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xoffset, const style::color &color) { QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xoffset, style::color color) {
auto result = style::colorizeImage(data->circle, color, QRect(xoffset, 0, half, size)); auto result = style::colorizeImage(data->circle, color, QRect(xoffset, 0, half, size));
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
return result; return result;
@ -194,14 +194,14 @@ void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st)
if (badgeData->left[index].isNull()) { if (badgeData->left[index].isNull()) {
int imgsize = size * cIntRetinaFactor(), imgsizehalf = sizehalf * cIntRetinaFactor(); int imgsize = size * cIntRetinaFactor(), imgsizehalf = sizehalf * cIntRetinaFactor();
createCircleMask(badgeData, size); createCircleMask(badgeData, size);
badgeData->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, 0, *bg)); badgeData->left[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, 0, bg));
badgeData->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, imgsize - imgsizehalf, *bg)); badgeData->right[index] = App::pixmapFromImageInPlace(colorizeCircleHalf(badgeData, imgsize, imgsizehalf, imgsize - imgsizehalf, bg));
} }
int bar = rect.width() - 2 * sizehalf; int bar = rect.width() - 2 * sizehalf;
p.drawPixmap(rect.x(), rect.y(), badgeData->left[index]); p.drawPixmap(rect.x(), rect.y(), badgeData->left[index]);
if (bar) { if (bar) {
p.fillRect(rect.x() + sizehalf, rect.y(), bar, rect.height(), *bg); p.fillRect(rect.x() + sizehalf, rect.y(), bar, rect.height(), bg);
} }
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]); p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]);
} }

View file

@ -535,7 +535,18 @@ void WorkingDirReady() {
} }
} }
object_ptr<SingleDelayedCall> MainThreadTaskHandler = { nullptr };
void MainThreadTaskAdded() {
if (!started()) {
return;
}
MainThreadTaskHandler->call();
}
void start() { void start() {
MainThreadTaskHandler.create(QCoreApplication::instance(), "onMainThreadTask");
SandboxData = new internal::Data(); SandboxData = new internal::Data();
SandboxData->LangSystemISO = psCurrentLanguage(); SandboxData->LangSystemISO = psCurrentLanguage();
@ -556,6 +567,7 @@ bool started() {
void finish() { void finish() {
delete SandboxData; delete SandboxData;
SandboxData = nullptr; SandboxData = nullptr;
MainThreadTaskHandler.destroy();
} }
uint64 UserTag() { uint64 UserTag() {

View file

@ -225,6 +225,8 @@ namespace Sandbox {
bool CheckBetaVersionDir(); bool CheckBetaVersionDir();
void WorkingDirReady(); void WorkingDirReady();
void MainThreadTaskAdded();
void start(); void start();
bool started(); bool started();
void finish(); void finish();

View file

@ -239,7 +239,7 @@ bool History::mySendActionUpdated(SendAction::Type type, bool doing) {
return true; return true;
} }
bool History::paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, const style::color &color, TimeMs ms) { bool History::paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, style::color color, TimeMs ms) {
if (_sendActionAnimation) { if (_sendActionAnimation) {
_sendActionAnimation.paint(p, color, x, y + st::normalFont->ascent, outerWidth, ms); _sendActionAnimation.paint(p, color, x, y + st::normalFont->ascent, outerWidth, ms);
auto animationWidth = _sendActionAnimation.width(); auto animationWidth = _sendActionAnimation.width();
@ -324,7 +324,7 @@ bool History::updateSendActionNeedsAnimating(TimeMs ms, bool force) {
} }
if (_sendActionString != newTypingString) { if (_sendActionString != newTypingString) {
_sendActionString = newTypingString; _sendActionString = newTypingString;
_sendActionText.setText(st::dialogsTextFont, _sendActionString, _textNameOptions); _sendActionText.setText(st::dialogsTextStyle, _sendActionString, _textNameOptions);
} }
} }
auto result = (!_typing.isEmpty() || !_sendActions.isEmpty()); auto result = (!_typing.isEmpty() || !_sendActions.isEmpty());

View file

@ -339,7 +339,7 @@ public:
void unregSendAction(UserData *from); void unregSendAction(UserData *from);
bool updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action); bool updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action);
bool mySendActionUpdated(SendAction::Type type, bool doing); bool mySendActionUpdated(SendAction::Type type, bool doing);
bool paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, const style::color &color, TimeMs ms); bool paintSendAction(Painter &p, int x, int y, int availableWidth, int outerWidth, style::color color, TimeMs ms);
void clearLastKeyboard(); void clearLastKeyboard();

View file

@ -346,7 +346,11 @@ botKbBg: menuBgOver;
botKbOverBg: menuBgOver; botKbOverBg: menuBgOver;
botKbDownBg: menuBgRipple; botKbDownBg: menuBgRipple;
botKbColor: windowBoldFgOver; botKbColor: windowBoldFgOver;
botKbFont: font(15px semibold); botKbStyle: TextStyle(defaultTextStyle) {
font: font(15px semibold);
linkFont: font(15px semibold);
linkFontOver: font(15px semibold);
}
botKbButton: BotKeyboardButton { botKbButton: BotKeyboardButton {
margin: 10px; margin: 10px;
padding: 10px; padding: 10px;
@ -404,3 +408,26 @@ historyUnreadBarFont: semiboldFont;
historyForwardChooseMargins: margins(30px, 10px, 30px, 10px); historyForwardChooseMargins: margins(30px, 10px, 30px, 10px);
historyForwardChooseFont: font(16px); historyForwardChooseFont: font(16px);
msgFileMenuSize: size(36px, 36px);
msgFileSize: 44px;
msgFilePadding: margins(14px, 12px, 11px, 12px);
msgFileThumbSize: 72px;
msgFileThumbPadding: margins(10px, 10px, 14px, 10px);
msgFileThumbNameTop: 12px;
msgFileThumbStatusTop: 32px;
msgFileThumbLinkTop: 60px;
msgFileNameTop: 16px;
msgFileStatusTop: 37px;
msgFileMinWidth: 294px;
msgFileTopMinus: 6px;
msgFileOverDuration: 200;
msgFileRadialLine: 3px;
msgVideoSize: size(320px, 240px);
msgWaveformBar: 2px;
msgWaveformSkip: 1px;
msgWaveformMin: 2px;
msgWaveformMax: 20px;

View file

@ -111,7 +111,7 @@ ReplyKeyboard::ReplyKeyboard(const HistoryItem *item, StylePtr &&s)
auto str = row.at(j).text; auto str = row.at(j).text;
button.type = row.at(j).type; button.type = row.at(j).type;
button.link = MakeShared<ReplyMarkupClickHandler>(item, i, j); button.link = MakeShared<ReplyMarkupClickHandler>(item, i, j);
button.text.setText(_st->textFont(), textOneLine(str), _textPlainOptions); button.text.setText(_st->textStyle(), textOneLine(str), _textPlainOptions);
button.characters = str.isEmpty() ? 1 : str.size(); button.characters = str.isEmpty() ? 1 : str.size();
} }
_rows.push_back(newRow); _rows.push_back(newRow);
@ -381,12 +381,12 @@ void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKe
} }
int tx = rect.x(), tw = rect.width(); int tx = rect.x(), tw = rect.width();
if (tw >= st::botKbFont->elidew + _st->padding * 2) { if (tw >= st::botKbStyle.font->elidew + _st->padding * 2) {
tx += _st->padding; tx += _st->padding;
tw -= _st->padding * 2; tw -= _st->padding * 2;
} else if (tw > st::botKbFont->elidew) { } else if (tw > st::botKbStyle.font->elidew) {
tx += (tw - st::botKbFont->elidew) / 2; tx += (tw - st::botKbStyle.font->elidew) / 2;
tw = st::botKbFont->elidew; tw = st::botKbStyle.font->elidew;
} }
button.text.drawElided(p, tx, rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top); button.text.drawElided(p, tx, rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top);
} }
@ -928,14 +928,14 @@ QString HistoryItem::inDialogsText() const {
void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const { void HistoryItem::drawInDialog(Painter &p, const QRect &r, bool active, bool selected, const HistoryItem *&cacheFor, Text &cache) const {
if (cacheFor != this) { if (cacheFor != this) {
cacheFor = this; cacheFor = this;
cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions); cache.setText(st::dialogsTextStyle, inDialogsText(), _textDlgOptions);
} }
if (r.width()) { if (r.width()) {
textstyleSet(&(active ? st::dialogsTextStyleActive : (selected ? st::dialogsTextStyleOver : st::dialogsTextStyle))); p.setTextPalette(active ? st::dialogsTextPaletteActive : (selected ? st::dialogsTextPaletteOver : st::dialogsTextPalette));
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg)); p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height); cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
textstyleRestore(); p.restoreTextPalette();
} }
} }

View file

@ -294,7 +294,7 @@ public:
} }
virtual void startPaint(Painter &p) const = 0; virtual void startPaint(Painter &p) const = 0;
virtual style::font textFont() const = 0; virtual const style::TextStyle &textStyle() const = 0;
int buttonSkip() const; int buttonSkip() const;
int buttonPadding() const; int buttonPadding() const;

View file

@ -223,7 +223,7 @@ HistoryPhoto::HistoryPhoto(HistoryItem *parent, PhotoData *photo, const QString
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
setLinks(MakeShared<PhotoOpenClickHandler>(_data), MakeShared<PhotoSaveClickHandler>(_data), MakeShared<PhotoCancelClickHandler>(_data)); setLinks(MakeShared<PhotoOpenClickHandler>(_data), MakeShared<PhotoSaveClickHandler>(_data), MakeShared<PhotoCancelClickHandler>(_data));
if (!caption.isEmpty()) { if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent)); _caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
} }
init(); init();
} }
@ -597,7 +597,7 @@ HistoryVideo::HistoryVideo(HistoryItem *parent, DocumentData *document, const QS
, _thumbw(1) , _thumbw(1)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
if (!caption.isEmpty()) { if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent)); _caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
} }
setDocumentLinks(_data); setDocumentLinks(_data);
@ -900,10 +900,14 @@ ImagePtr HistoryVideo::replyPreview() {
return _data->replyPreview; return _data->replyPreview;
} }
HistoryDocumentCaptioned::HistoryDocumentCaptioned()
: _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
}
HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(const HistoryDocument *that) HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(const HistoryDocument *that)
: _position(0) : a_progress(0., 0.)
, a_progress(0., 0.) , _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
, _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
} }
void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const { void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const {
@ -932,7 +936,7 @@ HistoryDocument::HistoryDocument(HistoryItem *parent, DocumentData *document, co
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
if (auto captioned = Get<HistoryDocumentCaptioned>()) { if (auto captioned = Get<HistoryDocumentCaptioned>()) {
captioned->_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent)); captioned->_caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
} }
} }
@ -1024,6 +1028,9 @@ void HistoryDocument::initDimensions() {
} else { } else {
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); _minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
} }
if (!isBubbleTop()) {
_minh -= st::msgFileTopMinus;
}
if (captioned) { if (captioned) {
auto captionw = _maxw - st::msgPadding.left() - st::msgPadding.right(); auto captionw = _maxw - st::msgPadding.left() - st::msgPadding.right();
@ -1048,6 +1055,9 @@ int HistoryDocument::resizeGetHeight(int width) {
} else { } else {
_height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); _height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
} }
if (!isBubbleTop()) {
_height -= st::msgFileTopMinus;
}
auto captionw = _width - st::msgPadding.left() - st::msgPadding.right(); auto captionw = _width - st::msgPadding.left() - st::msgPadding.right();
_height += captioned->_caption.countHeight(captionw); _height += captioned->_caption.countHeight(captionw);
if (isBubbleBottom()) { if (isBubbleBottom()) {
@ -1077,18 +1087,19 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
bool showPause = updateStatusText(); bool showPause = updateStatusText();
bool radial = isRadialAnimation(ms); bool radial = isRadialAnimation(ms);
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
int nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; int nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
if (auto thumbed = Get<HistoryDocumentThumbed>()) { if (auto thumbed = Get<HistoryDocumentThumbed>()) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop; nametop = st::msgFileThumbNameTop - topMinus;
nameright = st::msgFileThumbPadding.left(); nameright = st::msgFileThumbPadding.left();
statustop = st::msgFileThumbStatusTop; statustop = st::msgFileThumbStatusTop - topMinus;
linktop = st::msgFileThumbLinkTop; linktop = st::msgFileThumbLinkTop - topMinus;
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus;
auto inWebPage = (_parent->getMedia() != this); auto inWebPage = (_parent->getMedia() != this);
auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large; auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large;
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, _width));
QPixmap thumb; QPixmap thumb;
if (loaded) { if (loaded) {
thumb = _data->thumb->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); thumb = _data->thumb->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
@ -1098,7 +1109,7 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
if (selected) { if (selected) {
auto overlayCorners = inWebPage ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners; auto overlayCorners = inWebPage ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners;
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, overlayCorners); App::roundRect(p, rthumb, p.textPalette().selectOverlay, overlayCorners);
} }
if (radial || (!loaded && !_data->loading())) { if (radial || (!loaded && !_data->loading())) {
@ -1147,12 +1158,12 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
} }
} else { } else {
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
nametop = st::msgFileNameTop; nametop = st::msgFileNameTop - topMinus;
nameright = st::msgFilePadding.left(); nameright = st::msgFilePadding.left();
statustop = st::msgFileStatusTop; statustop = st::msgFileStatusTop - topMinus;
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, _width));
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (selected) { if (selected) {
p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected); p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected);
@ -1192,7 +1203,7 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
})(); })();
icon->paintInCenter(p, inner); icon->paintInCenter(p, inner);
} }
int32 namewidth = _width - nameleft - nameright; auto namewidth = _width - nameleft - nameright;
if (auto voice = Get<HistoryDocumentVoice>()) { if (auto voice = Get<HistoryDocumentVoice>()) {
const VoiceWaveform *wf = 0; const VoiceWaveform *wf = 0;
@ -1298,12 +1309,13 @@ HistoryTextState HistoryDocument::getState(int x, int y, HistoryStateRequest req
bool showPause = updateStatusText(); bool showPause = updateStatusText();
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (auto thumbed = Get<HistoryDocumentThumbed>()) { if (auto thumbed = Get<HistoryDocumentThumbed>()) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
linktop = st::msgFileThumbLinkTop; linktop = st::msgFileThumbLinkTop - topMinus;
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus;
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, _width));
if ((_data->loading() || _data->uploading() || !loaded) && rthumb.contains(x, y)) { if ((_data->loading() || _data->uploading() || !loaded) && rthumb.contains(x, y)) {
result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel; result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel;
@ -1317,9 +1329,9 @@ HistoryTextState HistoryDocument::getState(int x, int y, HistoryStateRequest req
} }
} }
} else { } else {
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, _width));
if ((_data->loading() || _data->uploading() || !loaded) && inner.contains(x, y)) { if ((_data->loading() || _data->uploading() || !loaded) && inner.contains(x, y)) {
result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel; result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel;
return result; return result;
@ -1477,6 +1489,10 @@ bool HistoryDocument::updateStatusText() const {
return showPause; return showPause;
} }
QMargins HistoryDocument::bubbleMargins() const {
return Get<HistoryDocumentThumbed>() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
}
void HistoryDocument::step_voiceProgress(float64 ms, bool timer) { void HistoryDocument::step_voiceProgress(float64 ms, bool timer) {
if (auto voice = Get<HistoryDocumentVoice>()) { if (auto voice = Get<HistoryDocumentVoice>()) {
if (voice->_playback) { if (voice->_playback) {
@ -1529,7 +1545,7 @@ HistoryGif::HistoryGif(HistoryItem *parent, DocumentData *document, const QStrin
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
if (!caption.isEmpty()) { if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent)); _caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
} }
_data->thumb->load(); _data->thumb->load();
@ -2215,13 +2231,10 @@ ClickHandlerPtr addContactClickHandler(HistoryItem *item) {
HistoryContact::HistoryContact(HistoryItem *parent, int32 userId, const QString &first, const QString &last, const QString &phone) : HistoryMedia(parent) HistoryContact::HistoryContact(HistoryItem *parent, int32 userId, const QString &first, const QString &last, const QString &phone) : HistoryMedia(parent)
, _userId(userId) , _userId(userId)
, _contact(0)
, _phonew(0)
, _fname(first) , _fname(first)
, _lname(last) , _lname(last)
, _phone(App::formatPhone(phone)) , _phone(App::formatPhone(phone)) {
, _linkw(0) { _name.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
_name.setText(st::semiboldFont, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
_phonew = st::normalFont->width(_phone); _phonew = st::normalFont->width(_phone);
} }
@ -2264,6 +2277,9 @@ void HistoryContact::initDimensions() {
} else { } else {
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); _minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
} }
if (!isBubbleTop()) {
_minh -= st::msgFileTopMinus;
}
_height = _minh; _height = _minh;
} }
@ -2279,21 +2295,22 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T
} }
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (_userId) { if (_userId) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop; nametop = st::msgFileThumbNameTop - topMinus;
nameright = st::msgFileThumbPadding.left(); nameright = st::msgFileThumbPadding.left();
statustop = st::msgFileThumbStatusTop; statustop = st::msgFileThumbStatusTop - topMinus;
linktop = st::msgFileThumbLinkTop; linktop = st::msgFileThumbLinkTop - topMinus;
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width));
if (_contact) { if (_contact) {
_contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y()); _contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y());
} else { } else {
p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % kUserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize)); p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % kUserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize));
} }
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners); App::roundRect(p, rthumb, p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
} }
bool over = ClickHandler::showAsActive(_linkl); bool over = ClickHandler::showAsActive(_linkl);
@ -2302,11 +2319,11 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T
p.drawTextLeft(nameleft, linktop, width, _link, _linkw); p.drawTextLeft(nameleft, linktop, width, _link, _linkw);
} else { } else {
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
nametop = st::msgFileNameTop; nametop = st::msgFileNameTop - topMinus;
nameright = st::msgFilePadding.left(); nameright = st::msgFilePadding.left();
statustop = st::msgFileStatusTop; statustop = st::msgFileStatusTop - topMinus;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width));
p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(_parent->id) % kUserColorsCount)->pixCircled(st::msgFileSize, st::msgFileSize)); p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(_parent->id) % kUserColorsCount)->pixCircled(st::msgFileSize, st::msgFileSize));
} }
int32 namewidth = width - nameleft - nameright; int32 namewidth = width - nameleft - nameright;
@ -2326,9 +2343,10 @@ HistoryTextState HistoryContact::getState(int x, int y, HistoryStateRequest requ
bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost; bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost;
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (_userId) { if (_userId) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
linktop = st::msgFileThumbLinkTop; linktop = st::msgFileThumbLinkTop - topMinus;
if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) { if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) {
result.link = _linkl; result.link = _linkl;
return result; return result;
@ -2375,6 +2393,7 @@ void HistoryContact::updateSentMedia(const MTPMessageMedia &media) {
} }
namespace { namespace {
QString siteNameFromUrl(const QString &url) { QString siteNameFromUrl(const QString &url) {
QUrl u(url); QUrl u(url);
QString pretty = u.isValid() ? u.toDisplayString() : url; QString pretty = u.isValid() ? u.toDisplayString() : url;
@ -2400,6 +2419,7 @@ int32 articleThumbHeight(PhotoData *thumb, int32 width) {
} }
int32 _lineHeight = 0; int32 _lineHeight = 0;
} // namespace } // namespace
HistoryWebPage::HistoryWebPage(HistoryItem *parent, WebPageData *data) : HistoryMedia(parent) HistoryWebPage::HistoryWebPage(HistoryItem *parent, WebPageData *data) : HistoryMedia(parent)
@ -2479,13 +2499,13 @@ void HistoryWebPage::initDimensions() {
} else if (_data->siteName == qstr("Instagram")) { } else if (_data->siteName == qstr("Instagram")) {
opts = &_instagramDescriptionOptions; opts = &_instagramDescriptionOptions;
} }
_description.setText(st::webPageDescriptionFont, text, *opts); _description.setText(st::webPageDescriptionStyle, text, *opts);
} }
if (_title.isEmpty() && !title.isEmpty()) { if (_title.isEmpty() && !title.isEmpty()) {
if (!_asArticle && !_attach && _description.isEmpty()) { if (!_asArticle && !_attach && _description.isEmpty()) {
title += _parent->skipBlock(); title += _parent->skipBlock();
} }
_title.setText(st::webPageTitleFont, title, _webpageTitleOptions); _title.setText(st::webPageTitleStyle, title, _webpageTitleOptions);
} }
if (!_siteNameWidth && !_data->siteName.isEmpty()) { if (!_siteNameWidth && !_data->siteName.isEmpty()) {
_siteNameWidth = st::webPageTitleFont->width(_data->siteName); _siteNameWidth = st::webPageTitleFont->width(_data->siteName);
@ -2682,7 +2702,7 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
} }
p.drawPixmapLeft(padding.left() + width - pw, tshift, _width, pix); p.drawPixmapLeft(padding.left() + width - pw, tshift, _width, pix);
if (selected) { if (selected) {
App::roundRect(p, rtlrect(padding.left() + width - pw, tshift, pw, _pixh, _width), textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners); App::roundRect(p, rtlrect(padding.left() + width - pw, tshift, pw, _pixh, _width), p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
} }
width -= pw + st::webPagePhotoDelta; width -= pw + st::webPagePhotoDelta;
} }
@ -2943,11 +2963,11 @@ void HistoryGame::initDimensions() {
if (_description.isEmpty() && !_data->description.isEmpty()) { if (_description.isEmpty() && !_data->description.isEmpty()) {
auto text = _data->description; auto text = _data->description;
if (!text.isEmpty()) { if (!text.isEmpty()) {
_description.setText(st::webPageDescriptionFont, text, _webpageDescriptionOptions); _description.setText(st::webPageDescriptionStyle, text, _webpageDescriptionOptions);
} }
} }
if (_title.isEmpty() && !title.isEmpty()) { if (_title.isEmpty() && !title.isEmpty()) {
_title.setText(st::webPageTitleFont, title, _webpageTitleOptions); _title.setText(st::webPageTitleStyle, title, _webpageTitleOptions);
} }
// init dimensions // init dimensions
@ -3183,7 +3203,7 @@ TextSelection HistoryGame::adjustSelection(TextSelection selection, TextSelectTy
} }
bool HistoryGame::consumeMessageText(const TextWithEntities &textWithEntities) { bool HistoryGame::consumeMessageText(const TextWithEntities &textWithEntities) {
_description.setMarkedText(st::webPageDescriptionFont, textWithEntities, itemTextOptions(_parent)); _description.setMarkedText(st::webPageDescriptionStyle, textWithEntities, itemTextOptions(_parent));
return true; return true;
} }
@ -3279,10 +3299,10 @@ HistoryLocation::HistoryLocation(HistoryItem *parent, const LocationCoords &coor
, _description(st::msgMinWidth) , _description(st::msgMinWidth)
, _link(new LocationClickHandler(coords)) { , _link(new LocationClickHandler(coords)) {
if (!title.isEmpty()) { if (!title.isEmpty()) {
_title.setText(st::webPageTitleFont, textClean(title), _webpageTitleOptions); _title.setText(st::webPageTitleStyle, textClean(title), _webpageTitleOptions);
} }
if (!description.isEmpty()) { if (!description.isEmpty()) {
_description.setText(st::webPageDescriptionFont, textClean(description), _webpageDescriptionOptions); _description.setText(st::webPageDescriptionStyle, textClean(description), _webpageDescriptionOptions);
} }
} }

View file

@ -295,7 +295,9 @@ struct HistoryDocumentThumbed : public RuntimeComponent<HistoryDocumentThumbed>
mutable QString _link; mutable QString _link;
}; };
struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned> { struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned> {
Text _caption = { int(st::msgFileMinWidth) - st::msgPadding.left() - st::msgPadding.right() }; HistoryDocumentCaptioned();
Text _caption;
}; };
struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed> { struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed> {
QString _name; QString _name;
@ -305,7 +307,7 @@ class HistoryDocument;
struct HistoryDocumentVoicePlayback { struct HistoryDocumentVoicePlayback {
HistoryDocumentVoicePlayback(const HistoryDocument *that); HistoryDocumentVoicePlayback(const HistoryDocument *that);
int32 _position; int32 _position = 0;
anim::value a_progress; anim::value a_progress;
BasicAnimation _a_progress; BasicAnimation _a_progress;
}; };
@ -384,9 +386,7 @@ public:
bool customInfoLayout() const override { bool customInfoLayout() const override {
return false; return false;
} }
QMargins bubbleMargins() const override { QMargins bubbleMargins() const override;
return Get<HistoryDocumentThumbed>() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
}
bool hideForwardedFrom() const override { bool hideForwardedFrom() const override {
return _data->song(); return _data->song();
} }
@ -631,14 +631,14 @@ public:
private: private:
int32 _userId; int32 _userId;
UserData *_contact; UserData *_contact = nullptr;
int32 _phonew; int _phonew = 0;
QString _fname, _lname, _phone; QString _fname, _lname, _phone;
Text _name; Text _name;
ClickHandlerPtr _linkl; ClickHandlerPtr _linkl;
int32 _linkw; int _linkw = 0;
QString _link; QString _link;
}; };

View file

@ -112,7 +112,7 @@ void HistoryMessageSigned::create(UserData *from, const QDateTime &date) {
if (timew + namew > st::maxSignatureSize) { if (timew + namew > st::maxSignatureSize) {
name = st::msgDateFont->elided(from->firstName, st::maxSignatureSize - timew); name = st::msgDateFont->elided(from->firstName, st::maxSignatureSize - timew);
} }
_signature.setText(st::msgDateFont, name + time, _textNameOptions); _signature.setText(st::msgDateTextStyle, name + time, _textNameOptions);
} }
int HistoryMessageSigned::maxWidth() const { int HistoryMessageSigned::maxWidth() const {
@ -123,7 +123,7 @@ void HistoryMessageEdited::create(const QDateTime &editDate, const QDateTime &da
_editDate = editDate; _editDate = editDate;
QString time = date.toString(cTimeFormat()); QString time = date.toString(cTimeFormat());
_edited.setText(st::msgDateFont, lang(lng_edited) + ' ' + time, _textNameOptions); _edited.setText(st::msgDateTextStyle, lang(lng_edited) + ' ' + time, _textNameOptions);
} }
int HistoryMessageEdited::maxWidth() const { int HistoryMessageEdited::maxWidth() const {
@ -151,9 +151,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
} }
} }
TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto }; TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto };
textstyleSet(&st::inFwdTextStyle); _text.setText(st::fwdTextStyle, text, opts);
_text.setText(st::msgServiceNameFont, text, opts);
textstyleRestore();
_text.setLink(1, (_originalId && _authorOriginal->isChannel()) ? goToMessageClickHandler(_authorOriginal, _originalId) : _authorOriginal->openLink()); _text.setLink(1, (_originalId && _authorOriginal->isChannel()) ? goToMessageClickHandler(_authorOriginal, _originalId) : _authorOriginal->openLink());
if (via) { if (via) {
_text.setLink(2, via->_lnk); _text.setLink(2, via->_lnk);
@ -174,7 +172,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) {
} }
if (replyToMsg) { if (replyToMsg) {
replyToText.setText(st::msgFont, textClean(replyToMsg->inReplyText()), _textDlgOptions); replyToText.setText(st::messageTextStyle, textClean(replyToMsg->inReplyText()), _textDlgOptions);
updateName(); updateName();
@ -214,7 +212,7 @@ bool HistoryMessageReply::isNameUpdated() const {
void HistoryMessageReply::updateName() const { void HistoryMessageReply::updateName() const {
if (replyToMsg) { if (replyToMsg) {
QString name = (_replyToVia && replyToMsg->author()->isUser()) ? replyToMsg->author()->asUser()->firstName : App::peerName(replyToMsg->author()); QString name = (_replyToVia && replyToMsg->author()->isUser()) ? replyToMsg->author()->asUser()->firstName : App::peerName(replyToMsg->author());
replyToName.setText(st::msgServiceNameFont, name, _textNameOptions); replyToName.setText(st::fwdTextStyle, name, _textNameOptions);
replyToVersion = replyToMsg->author()->nameVersion; replyToVersion = replyToMsg->author()->nameVersion;
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false; bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0; int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
@ -248,12 +246,12 @@ void HistoryMessageReply::itemRemoved(HistoryMessage *holder, HistoryItem *remov
void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, int y, int w, PaintFlags flags) const { void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, int y, int w, PaintFlags flags) const {
bool selected = (flags & PaintSelected), outbg = holder->hasOutLayout(); bool selected = (flags & PaintSelected), outbg = holder->hasOutLayout();
const style::color *bar = &st::msgImgReplyBarColor; style::color bar = st::msgImgReplyBarColor;
if (flags & PaintInBubble) { if (flags & PaintInBubble) {
bar = &((flags & PaintSelected) ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor)); bar = (flags & PaintSelected) ? (outbg ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (outbg ? st::msgOutReplyBarColor : st::msgInReplyBarColor);
} }
QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x)); QRect rbar(rtlrect(x + st::msgReplyBarPos.x(), y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height(), w + 2 * x));
p.fillRect(rbar, *bar); p.fillRect(rbar, bar);
if (w > st::msgReplyBarSkip) { if (w > st::msgReplyBarSkip) {
if (replyToMsg) { if (replyToMsg) {
@ -266,7 +264,7 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in
QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x)); QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x));
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
if (selected) { if (selected) {
App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners); App::roundRect(p, to, p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
} }
} }
} }
@ -305,8 +303,8 @@ void HistoryMessage::KeyboardStyle::startPaint(Painter &p) const {
p.setPen(st::msgServiceFg); p.setPen(st::msgServiceFg);
} }
style::font HistoryMessage::KeyboardStyle::textFont() const { const style::TextStyle &HistoryMessage::KeyboardStyle::textStyle() const {
return st::msgServiceFont; return st::serviceTextStyle;
} }
void HistoryMessage::KeyboardStyle::repaint(const HistoryItem *item) const { void HistoryMessage::KeyboardStyle::repaint(const HistoryItem *item) const {
@ -1026,22 +1024,18 @@ void HistoryMessage::setText(const TextWithEntities &textWithEntities) {
if (mediaDisplayed && _media->consumeMessageText(textWithEntities)) { if (mediaDisplayed && _media->consumeMessageText(textWithEntities)) {
setEmptyText(); setEmptyText();
} else { } else {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
if (_media && _media->isDisplayed() && !_media->isAboveMessage()) { if (_media && _media->isDisplayed() && !_media->isAboveMessage()) {
_text.setMarkedText(st::msgFont, textWithEntities, itemTextOptions(this)); _text.setMarkedText(st::messageTextStyle, textWithEntities, itemTextOptions(this));
} else { } else {
_text.setMarkedText(st::msgFont, { textWithEntities.text + skipBlock(), textWithEntities.entities }, itemTextOptions(this)); _text.setMarkedText(st::messageTextStyle, { textWithEntities.text + skipBlock(), textWithEntities.entities }, itemTextOptions(this));
} }
textstyleRestore();
_textWidth = -1; _textWidth = -1;
_textHeight = 0; _textHeight = 0;
} }
} }
void HistoryMessage::setEmptyText() { void HistoryMessage::setEmptyText() {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle)); _text.setMarkedText(st::messageTextStyle, { QString(), EntitiesInText() }, itemTextOptions(this));
_text.setMarkedText(st::msgFont, { QString(), EntitiesInText() }, itemTextOptions(this));
textstyleRestore();
_textWidth = -1; _textWidth = -1;
_textHeight = 0; _textHeight = 0;
@ -1271,12 +1265,12 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T
float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration)); float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
float64 o = p.opacity(); float64 o = p.opacity();
p.setOpacity(o * dt); p.setOpacity(o * dt);
p.fillRect(0, skiph, _history->width, height - skiph, textstyleCurrent()->selectOverlay->b); p.fillRect(0, skiph, _history->width, height - skiph, st::defaultTextPalette.selectOverlay);
p.setOpacity(o); p.setOpacity(o);
} }
} }
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle)); p.setTextPalette(outbg ? st::outTextPalette : st::inTextPalette);
if (auto keyboard = inlineReplyKeyboard()) { if (auto keyboard = inlineReplyKeyboard()) {
int h = st::msgBotKbButton.margin + keyboard->naturalHeight(); int h = st::msgBotKbButton.margin + keyboard->naturalHeight();
@ -1344,7 +1338,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T
p.translate(-left, -top); p.translate(-left, -top);
} }
textstyleRestore(); p.restoreTextPalette();
auto reply = Get<HistoryMessageReply>(); auto reply = Get<HistoryMessageReply>();
if (reply && reply->isNameUpdated()) { if (reply && reply->isNameUpdated()) {
@ -1382,9 +1376,9 @@ void HistoryMessage::paintForwardedInfo(Painter &p, QRect &trect, bool selected)
auto fwd = Get<HistoryMessageForwarded>(); auto fwd = Get<HistoryMessageForwarded>();
bool breakEverywhere = (fwd->_text.countHeight(trect.width()) > 2 * serviceFont->height); bool breakEverywhere = (fwd->_text.countHeight(trect.width()) > 2 * serviceFont->height);
textstyleSet(&(selected ? (hasOutLayout() ? st::outFwdTextStyleSelected : st::inFwdTextStyleSelected) : (hasOutLayout() ? st::outFwdTextStyle : st::inFwdTextStyle))); p.setTextPalette(selected ? (hasOutLayout() ? st::outFwdTextPaletteSelected : st::inFwdTextPaletteSelected) : (hasOutLayout() ? st::outFwdTextPalette : st::inFwdTextPalette));
fwd->_text.drawElided(p, trect.x(), trect.y(), trect.width(), 2, style::al_left, 0, -1, 0, breakEverywhere); fwd->_text.drawElided(p, trect.x(), trect.y(), trect.width(), 2, style::al_left, 0, -1, 0, breakEverywhere);
textstyleSet(&(hasOutLayout() ? st::outTextStyle : st::inTextStyle)); p.setTextPalette(hasOutLayout() ? st::outTextPalette : st::inTextPalette);
trect.setY(trect.y() + (((fwd->_text.maxWidth() > trect.width()) ? 2 : 1) * serviceFont->height)); trect.setY(trect.y() + (((fwd->_text.maxWidth() > trect.width()) ? 2 : 1) * serviceFont->height));
} }
@ -1478,10 +1472,8 @@ int HistoryMessage::performResizeGetHeight(int width) {
} else { } else {
auto textWidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 1); auto textWidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 1);
if (textWidth != _textWidth) { if (textWidth != _textWidth) {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
_textWidth = textWidth; _textWidth = textWidth;
_textHeight = _text.countHeight(textWidth); _textHeight = _text.countHeight(textWidth);
textstyleRestore();
} }
_height = _textHeight; _height = _textHeight;
} }
@ -1676,9 +1668,7 @@ bool HistoryMessage::getStateForwardedInfo(int x, int y, QRect &trect, HistoryTe
if (breakEverywhere) { if (breakEverywhere) {
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere; textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
} }
textstyleSet(&st::inFwdTextStyle);
*outResult = fwd->_text.getState(x - trect.left(), y - trect.top(), trect.width(), textRequest); *outResult = fwd->_text.getState(x - trect.left(), y - trect.top(), trect.width(), textRequest);
textstyleRestore();
outResult->symbol = 0; outResult->symbol = 0;
outResult->afterSymbol = false; outResult->afterSymbol = false;
if (breakEverywhere) { if (breakEverywhere) {
@ -1722,9 +1712,7 @@ bool HistoryMessage::getStateViaBotIdInfo(int x, int y, QRect &trect, HistoryTex
bool HistoryMessage::getStateText(int x, int y, QRect &trect, HistoryTextState *outResult, const HistoryStateRequest &request) const { bool HistoryMessage::getStateText(int x, int y, QRect &trect, HistoryTextState *outResult, const HistoryStateRequest &request) const {
if (trect.contains(x, y)) { if (trect.contains(x, y)) {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
*outResult = _text.getState(x - trect.x(), y - trect.y(), trect.width(), request.forText()); *outResult = _text.getState(x - trect.x(), y - trect.y(), trect.width(), request.forText());
textstyleRestore();
return true; return true;
} }
return false; return false;
@ -2105,9 +2093,7 @@ QString HistoryService::inReplyText() const {
} }
void HistoryService::setServiceText(const QString &text, const Links &links) { void HistoryService::setServiceText(const QString &text, const Links &links) {
textstyleSet(&st::serviceTextStyle); _text.setText(st::serviceTextStyle, text, _historySrvOptions);
_text.setText(st::msgServiceFont, text, _historySrvOptions);
textstyleRestore();
for (int i = 0, count = links.size(); i != count; ++i) { for (int i = 0, count = links.size(); i != count; ++i) {
_text.setLink(1 + i, links.at(i)); _text.setLink(1 + i, links.at(i));
} }
@ -2169,9 +2155,7 @@ int32 HistoryService::resizeGetHeight_(int32 width) {
int32 nwidth = qMax(width - st::msgServicePadding.left() - st::msgServicePadding.right(), 0); int32 nwidth = qMax(width - st::msgServicePadding.left() - st::msgServicePadding.right(), 0);
if (nwidth != _textWidth) { if (nwidth != _textWidth) {
_textWidth = nwidth; _textWidth = nwidth;
textstyleSet(&st::serviceTextStyle);
_textHeight = _text.countHeight(nwidth); _textHeight = _text.countHeight(nwidth);
textstyleRestore();
} }
if (width >= _maxw) { if (width >= _maxw) {
_height += _minh; _height += _minh;
@ -2231,11 +2215,9 @@ HistoryTextState HistoryService::getState(int x, int y, HistoryStateRequest requ
auto outer = QRect(left, st::msgServiceMargin.top(), width, height); auto outer = QRect(left, st::msgServiceMargin.top(), width, height);
auto trect = outer.marginsAdded(-st::msgServicePadding); auto trect = outer.marginsAdded(-st::msgServicePadding);
if (trect.contains(x, y)) { if (trect.contains(x, y)) {
textstyleSet(&st::serviceTextStyle);
auto textRequest = request.forText(); auto textRequest = request.forText();
textRequest.align = style::al_center; textRequest.align = style::al_center;
result = _text.getState(x - trect.x(), y - trect.y(), trect.width(), textRequest); result = _text.getState(x - trect.x(), y - trect.y(), trect.width(), textRequest);
textstyleRestore();
if (auto gamescore = Get<HistoryServiceGameScore>()) { if (auto gamescore = Get<HistoryServiceGameScore>()) {
if (!result.link && result.cursor == HistoryInTextCursorState && outer.contains(x, y)) { if (!result.link && result.cursor == HistoryInTextCursorState && outer.contains(x, y)) {
result.link = gamescore->lnk; result.link = gamescore->lnk;

View file

@ -211,7 +211,7 @@ private:
int buttonRadius() const override; int buttonRadius() const override;
void startPaint(Painter &p) const override; void startPaint(Painter &p) const override;
style::font textFont() const override; const style::TextStyle &textStyle() const override;
void repaint(const HistoryItem *item) const override; void repaint(const HistoryItem *item) const override;
protected: protected:

View file

@ -196,16 +196,15 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
} else { } else {
int skiph = st::msgServiceMargin.top() - st::msgServiceMargin.bottom(); int skiph = st::msgServiceMargin.top() - st::msgServiceMargin.bottom();
textstyleSet(&st::inTextStyle);
float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration)); float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
float64 o = p.opacity(); float64 o = p.opacity();
p.setOpacity(o * dt); p.setOpacity(o * dt);
p.fillRect(0, skiph, message->history()->width, message->height() - skiph, textstyleCurrent()->selectOverlay->b); p.fillRect(0, skiph, message->history()->width, message->height() - skiph, st::defaultTextPalette.selectOverlay);
p.setOpacity(o); p.setOpacity(o);
} }
} }
textstyleSet(&st::serviceTextStyle); p.setTextPalette(st::serviceTextPalette);
if (auto media = message->getMedia()) { if (auto media = message->getMedia()) {
height -= st::msgServiceMargin.top() + media->height(); height -= st::msgServiceMargin.top() + media->height();
@ -229,7 +228,7 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
p.setFont(st::msgServiceFont); p.setFont(st::msgServiceFont);
message->_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, context.selection, false); message->_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, context.selection, false);
textstyleRestore(); p.restoreTextPalette();
} }
void ServiceMessagePainter::paintDate(Painter &p, const QDateTime &date, int y, int w) { void ServiceMessagePainter::paintDate(Painter &p, const QDateTime &date, int y, int w) {

View file

@ -422,7 +422,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
bool noHistoryDisplayed = _firstLoading || historyDisplayedEmpty; bool noHistoryDisplayed = _firstLoading || historyDisplayedEmpty;
if (!_firstLoading && _botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) { if (!_firstLoading && _botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
if (r.y() < _botAbout->rect.y() + _botAbout->rect.height() && r.y() + r.height() > _botAbout->rect.y()) { if (r.y() < _botAbout->rect.y() + _botAbout->rect.height() && r.y() + r.height() > _botAbout->rect.y()) {
textstyleSet(&st::inTextStyle); p.setTextPalette(st::inTextPalette);
App::roundRect(p, _botAbout->rect, st::msgInBg, MessageInCorners, &st::msgInShadow); App::roundRect(p, _botAbout->rect, st::msgInBg, MessageInCorners, &st::msgInShadow);
p.setFont(st::msgNameFont); p.setFont(st::msgNameFont);
@ -432,7 +432,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
p.setPen(st::historyTextInFg); p.setPen(st::historyTextInFg);
_botAbout->info->text.draw(p, _botAbout->rect.left() + st::msgPadding.left(), _botAbout->rect.top() + st::msgPadding.top() + st::msgNameFont->height + st::botDescSkip, _botAbout->width); _botAbout->info->text.draw(p, _botAbout->rect.left() + st::msgPadding.left(), _botAbout->rect.top() + st::msgPadding.top() + st::msgNameFont->height + st::botDescSkip, _botAbout->width);
textstyleRestore(); p.restoreTextPalette();
} }
} else if (noHistoryDisplayed) { } else if (noHistoryDisplayed) {
HistoryLayout::paintEmpty(p, width(), height()); HistoryLayout::paintEmpty(p, width(), height());
@ -1637,7 +1637,7 @@ void HistoryInner::updateBotInfo(bool recount) {
int newh = 0; int newh = 0;
if (_botAbout && !_botAbout->info->description.isEmpty()) { if (_botAbout && !_botAbout->info->description.isEmpty()) {
if (_botAbout->info->text.isEmpty()) { if (_botAbout->info->text.isEmpty()) {
_botAbout->info->text.setText(st::msgFont, _botAbout->info->description, _historyBotNoMonoOptions); _botAbout->info->text.setText(st::messageTextStyle, _botAbout->info->description, _historyBotNoMonoOptions);
if (recount) { if (recount) {
int32 tw = _scroll->width() - st::msgMargin.left() - st::msgMargin.right(); int32 tw = _scroll->width() - st::msgMargin.left() - st::msgMargin.right();
if (tw > st::msgMaxWidth) tw = st::msgMaxWidth; if (tw > st::msgMaxWidth) tw = st::msgMaxWidth;
@ -2359,9 +2359,9 @@ MessageField::MessageField(HistoryWidget *history, const style::FlatTextarea &st
} }
bool MessageField::hasSendText() const { bool MessageField::hasSendText() const {
auto &text(getTextWithTags().text); auto &text = getTextWithTags().text;
for (auto *ch = text.constData(), *e = ch + text.size(); ch != e; ++ch) { for (auto *ch = text.constData(), *e = ch + text.size(); ch != e; ++ch) {
ushort code = ch->unicode(); auto code = ch->unicode();
if (code != ' ' && code != '\n' && code != '\r' && !chReplacedBySpace(code)) { if (code != ' ' && code != '\n' && code != '\r' && !chReplacedBySpace(code)) {
return true; return true;
} }
@ -2472,11 +2472,11 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
void BotKeyboard::Style::startPaint(Painter &p) const { void BotKeyboard::Style::startPaint(Painter &p) const {
p.setPen(st::botKbColor); p.setPen(st::botKbColor);
p.setFont(st::botKbFont); p.setFont(st::botKbStyle.font);
} }
style::font BotKeyboard::Style::textFont() const { const style::TextStyle &BotKeyboard::Style::textStyle() const {
return st::botKbFont; return st::botKbStyle;
} }
void BotKeyboard::Style::repaint(const HistoryItem *item) const { void BotKeyboard::Style::repaint(const HistoryItem *item) const {
@ -2677,28 +2677,28 @@ void BotKeyboard::updateSelected() {
HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : TWidget(parent) HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : TWidget(parent)
, _forwardSelected(forwardSelected) , _forwardSelected(forwardSelected)
, _send(this, lang(lng_forward_send), st::defaultBoxButton) , _send(this, lang(lng_forward_send), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { , _cancel(this, lang(lng_cancel), st::defaultBoxButton) {
init(); init();
} }
HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : TWidget(parent) HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : TWidget(parent)
, _sharedContact(sharedContact) , _sharedContact(sharedContact)
, _send(this, lang(lng_forward_send), st::defaultBoxButton) , _send(this, lang(lng_forward_send), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { , _cancel(this, lang(lng_cancel), st::defaultBoxButton) {
init(); init();
} }
HistoryHider::HistoryHider(MainWidget *parent) : TWidget(parent) HistoryHider::HistoryHider(MainWidget *parent) : TWidget(parent)
, _sendPath(true) , _sendPath(true)
, _send(this, lang(lng_forward_send), st::defaultBoxButton) , _send(this, lang(lng_forward_send), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { , _cancel(this, lang(lng_cancel), st::defaultBoxButton) {
init(); init();
} }
HistoryHider::HistoryHider(MainWidget *parent, const QString &botAndQuery) : TWidget(parent) HistoryHider::HistoryHider(MainWidget *parent, const QString &botAndQuery) : TWidget(parent)
, _botAndQuery(botAndQuery) , _botAndQuery(botAndQuery)
, _send(this, lang(lng_forward_send), st::defaultBoxButton) , _send(this, lang(lng_forward_send), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { , _cancel(this, lang(lng_cancel), st::defaultBoxButton) {
init(); init();
} }
@ -2706,7 +2706,7 @@ HistoryHider::HistoryHider(MainWidget *parent, const QString &url, const QString
, _shareUrl(url) , _shareUrl(url)
, _shareText(text) , _shareText(text)
, _send(this, lang(lng_forward_send), st::defaultBoxButton) , _send(this, lang(lng_forward_send), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { , _cancel(this, lang(lng_cancel), st::defaultBoxButton) {
init(); init();
} }
@ -2746,9 +2746,7 @@ void HistoryHider::paintEvent(QPaintEvent *e) {
App::roundRect(p, _box, st::boxBg, BoxCorners); App::roundRect(p, _box, st::boxBg, BoxCorners);
p.setPen(st::boxTextFg); p.setPen(st::boxTextFg);
textstyleSet(&st::boxTextStyle);
_toText.drawLeftElided(p, _box.left() + st::boxPadding.left(), _box.y() + st::boxTopMargin + st::boxPadding.top(), _toTextWidth + 2, width(), 1, style::al_left); _toText.drawLeftElided(p, _box.left() + st::boxPadding.left(), _box.y() + st::boxTopMargin + st::boxPadding.top(), _toTextWidth + 2, width(), 1, style::al_left);
textstyleRestore();
} else { } else {
auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right(); auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right();
auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom(); auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom();
@ -2856,7 +2854,7 @@ void HistoryHider::resizeEvent(QResizeEvent *e) {
bool HistoryHider::offerPeer(PeerId peer) { bool HistoryHider::offerPeer(PeerId peer) {
if (!peer) { if (!peer) {
_offered = nullptr; _offered = nullptr;
_toText.setText(st::boxTextFont, QString()); _toText.setText(st::boxTextStyle, QString());
_toTextWidth = 0; _toTextWidth = 0;
resizeEvent(nullptr); resizeEvent(nullptr);
return false; return false;
@ -2896,9 +2894,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
return false; return false;
} }
textstyleSet(&st::boxTextStyle); _toText.setText(st::boxTextStyle, phrase, _textNameOptions);
_toText.setText(st::boxTextFont, phrase, _textNameOptions);
textstyleRestore();
_toTextWidth = _toText.maxWidth(); _toTextWidth = _toText.maxWidth();
if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) { if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right()) {
_toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right(); _toTextWidth = _box.width() - st::boxPadding.left() - st::boxLayerButtonPadding.right();
@ -6089,7 +6085,7 @@ void HistoryWidget::onKbToggle(bool manual) {
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0; _kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0;
if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) { if (_kbReplyTo && !_editMsgId && !_replyToId && fieldEnabled) {
updateReplyToName(); updateReplyToName();
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions); _replyEditMsgText.setText(st::messageTextStyle, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
_fieldBarCancel->show(); _fieldBarCancel->show();
updateMouseTracking(); updateMouseTracking();
} }
@ -6108,7 +6104,7 @@ void HistoryWidget::onKbToggle(bool manual) {
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0; _kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0;
if (_kbReplyTo && !_editMsgId && !_replyToId) { if (_kbReplyTo && !_editMsgId && !_replyToId) {
updateReplyToName(); updateReplyToName();
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions); _replyEditMsgText.setText(st::messageTextStyle, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
_fieldBarCancel->show(); _fieldBarCancel->show();
updateMouseTracking(); updateMouseTracking();
} }
@ -6180,15 +6176,14 @@ bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
if (!_history) return false; if (!_history) return false;
auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0; auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0;
decreaseWidth += increaseLeft;
auto nameleft = st::topBarArrowPadding.right() + increaseLeft; auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
auto nametop = st::topBarArrowPadding.top(); auto nametop = st::topBarArrowPadding.top();
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height; auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
auto namewidth = width() - decreaseWidth - st::topBarArrowPadding.left() - st::topBarArrowPadding.right(); auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) { if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg); p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
p.drawText(nameleft, st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height + st::dialogsTextFont->ascent, _titlePeerText); p.drawText(nameleft, statustop + st::dialogsTextFont->ascent, _titlePeerText);
} }
p.setPen(st::dialogsNameFg); p.setPen(st::dialogsNameFg);
@ -6374,8 +6369,8 @@ void HistoryWidget::moveFieldControls() {
} }
void HistoryWidget::updateFieldSize() { void HistoryWidget::updateFieldSize() {
bool kbShowShown = _history && !_kbShown && _keyboard->hasMarkup(); auto kbShowShown = _history && !_kbShown && _keyboard->hasMarkup();
int fieldWidth = width() - _attachToggle->width(); auto fieldWidth = width() - _attachToggle->width() - st::historySendRight;
fieldWidth -= _send->width(); fieldWidth -= _send->width();
fieldWidth -= _attachEmoji->width(); fieldWidth -= _attachEmoji->width();
if (kbShowShown) fieldWidth -= _botKeyboardShow->width(); if (kbShowShown) fieldWidth -= _botKeyboardShow->width();
@ -7382,7 +7377,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
_kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0; _kbReplyTo = (_peer->isChat() || _peer->isChannel() || _keyboard->forceReply()) ? App::histItemById(_keyboard->forMsgId()) : 0;
if (_kbReplyTo && !_replyToId) { if (_kbReplyTo && !_replyToId) {
updateReplyToName(); updateReplyToName();
_replyEditMsgText.setText(st::msgFont, textClean(_kbReplyTo->inReplyText()), _textDlgOptions); _replyEditMsgText.setText(st::messageTextStyle, textClean(_kbReplyTo->inReplyText()), _textDlgOptions);
_fieldBarCancel->show(); _fieldBarCancel->show();
updateMouseTracking(); updateMouseTracking();
} }
@ -7638,7 +7633,7 @@ void HistoryWidget::updatePinnedBar(bool force) {
_pinnedBar->msg = App::histItemById(_history->channelId(), _pinnedBar->msgId); _pinnedBar->msg = App::histItemById(_history->channelId(), _pinnedBar->msgId);
} }
if (_pinnedBar->msg) { if (_pinnedBar->msg) {
_pinnedBar->text.setText(st::msgFont, textClean(_pinnedBar->msg->notificationText()), _textDlgOptions); _pinnedBar->text.setText(st::messageTextStyle, textClean(_pinnedBar->msg->notificationText()), _textDlgOptions);
update(); update();
} else if (force) { } else if (force) {
if (_peer && _peer->isMegagroup()) { if (_peer && _peer->isMegagroup()) {
@ -7870,7 +7865,7 @@ void HistoryWidget::onReplyToMessage() {
} else { } else {
_replyEditMsg = to; _replyEditMsg = to;
_replyToId = to->id; _replyToId = to->id;
_replyEditMsgText.setText(st::msgFont, textClean(_replyEditMsg->inReplyText()), _textDlgOptions); _replyEditMsgText.setText(st::messageTextStyle, textClean(_replyEditMsg->inReplyText()), _textDlgOptions);
updateBotKeyboard(); updateBotKeyboard();
@ -8207,13 +8202,13 @@ void HistoryWidget::updatePreview() {
_fieldBarCancel->show(); _fieldBarCancel->show();
updateMouseTracking(); updateMouseTracking();
if (_previewData->pendingTill) { if (_previewData->pendingTill) {
_previewTitle.setText(st::msgServiceNameFont, lang(lng_preview_loading), _textNameOptions); _previewTitle.setText(st::msgNameStyle, lang(lng_preview_loading), _textNameOptions);
#ifndef OS_MAC_OLD #ifndef OS_MAC_OLD
auto linkText = _previewLinks.splitRef(' ').at(0).toString(); auto linkText = _previewLinks.splitRef(' ').at(0).toString();
#else // OS_MAC_OLD #else // OS_MAC_OLD
auto linkText = _previewLinks.split(' ').at(0); auto linkText = _previewLinks.split(' ').at(0);
#endif // OS_MAC_OLD #endif // OS_MAC_OLD
_previewDescription.setText(st::msgFont, textClean(linkText), _textDlgOptions); _previewDescription.setText(st::messageTextStyle, textClean(linkText), _textDlgOptions);
int32 t = (_previewData->pendingTill - unixtime()) * 1000; int32 t = (_previewData->pendingTill - unixtime()) * 1000;
if (t <= 0) t = 1; if (t <= 0) t = 1;
@ -8244,8 +8239,8 @@ void HistoryWidget::updatePreview() {
title = lang(lng_attach_photo); title = lang(lng_attach_photo);
} }
} }
_previewTitle.setText(st::msgServiceNameFont, title, _textNameOptions); _previewTitle.setText(st::msgNameStyle, title, _textNameOptions);
_previewDescription.setText(st::msgFont, textClean(desc), _textDlgOptions); _previewDescription.setText(st::messageTextStyle, textClean(desc), _textDlgOptions);
} }
} else if (!readyToForward() && !replyToId() && !_editMsgId) { } else if (!readyToForward() && !replyToId() && !_editMsgId) {
_fieldBarCancel->hide(); _fieldBarCancel->hide();
@ -8509,7 +8504,7 @@ void HistoryWidget::updateReplyEditTexts(bool force) {
_replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId); _replyEditMsg = App::histItemById(_channel, _editMsgId ? _editMsgId : _replyToId);
} }
if (_replyEditMsg) { if (_replyEditMsg) {
_replyEditMsgText.setText(st::msgFont, textClean(_replyEditMsg->inReplyText()), _textDlgOptions); _replyEditMsgText.setText(st::messageTextStyle, textClean(_replyEditMsg->inReplyText()), _textDlgOptions);
updateBotKeyboard(); updateBotKeyboard();
@ -8539,7 +8534,7 @@ void HistoryWidget::updateForwarding(bool force) {
void HistoryWidget::updateReplyToName() { void HistoryWidget::updateReplyToName() {
if (_editMsgId) return; if (_editMsgId) return;
if (!_replyEditMsg && (_replyToId || !_kbReplyTo)) return; if (!_replyEditMsg && (_replyToId || !_kbReplyTo)) return;
_replyToName.setText(st::msgServiceNameFont, App::peerName((_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()), _textNameOptions); _replyToName.setText(st::msgNameStyle, App::peerName((_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()), _textNameOptions);
_replyToNameVersion = (_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()->nameVersion; _replyToNameVersion = (_replyEditMsg ? _replyEditMsg : _kbReplyTo)->author()->nameVersion;
} }
@ -8826,7 +8821,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
QRect to, from; QRect to, from;
App::main()->backgroundParams(fill, to, from); Window::Theme::ComputeBackgroundRects(fill, pix.size(), to, from);
to.moveTop(to.top() + fromy); to.moveTop(to.top() + fromy);
p.drawPixmap(to, pix, from); p.drawPixmap(to, pix, from);
} }

View file

@ -439,7 +439,7 @@ private:
int buttonRadius() const override; int buttonRadius() const override;
void startPaint(Painter &p) const override; void startPaint(Painter &p) const override;
style::font textFont() const override; const style::TextStyle &textStyle() const override;
void repaint(const HistoryItem *item) const override; void repaint(const HistoryItem *item) const override;
protected: protected:

View file

@ -572,7 +572,7 @@ void Video::initDimensions() {
if (title.isEmpty()) { if (title.isEmpty()) {
title = lang(lng_media_video); title = lang(lng_media_video);
} }
_title.setText(st::semiboldFont, title, titleOpts); _title.setText(st::semiboldTextStyle, title, titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height); int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = withThumb ? (titleHeight > st::semiboldFont->height ? 1 : 2) : 3; int32 descriptionLines = withThumb ? (titleHeight > st::semiboldFont->height ? 1 : 2) : 3;
@ -582,7 +582,7 @@ void Video::initDimensions() {
if (description.isEmpty()) { if (description.isEmpty()) {
description = _duration; description = _duration;
} }
_description.setText(st::normalFont, description, descriptionOpts); _description.setText(st::defaultTextStyle, description, descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height); int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = st::inlineThumbSize; _minh = st::inlineThumbSize;
@ -683,10 +683,10 @@ void File::initDimensions() {
int textWidth = _maxw - (st::msgFileSize + st::inlineThumbSkip); int textWidth = _maxw - (st::msgFileSize + st::inlineThumbSkip);
TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto }; TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->getLayoutTitle()), titleOpts); _title.setText(st::semiboldTextStyle, textOneLine(_result->getLayoutTitle()), titleOpts);
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto }; TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, _result->getLayoutDescription(), descriptionOpts); _description.setText(st::defaultTextStyle, _result->getLayoutDescription(), descriptionOpts);
_minh = st::msgFileSize; _minh = st::msgFileSize;
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder; _minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
@ -892,11 +892,11 @@ void Contact::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip); int32 textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip);
TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto }; TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->getLayoutTitle()), titleOpts); _title.setText(st::semiboldTextStyle, textOneLine(_result->getLayoutTitle()), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), st::semiboldFont->height); int32 titleHeight = qMin(_title.countHeight(_maxw), st::semiboldFont->height);
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto }; TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, _result->getLayoutDescription(), descriptionOpts); _description.setText(st::defaultTextStyle, _result->getLayoutDescription(), descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), st::normalFont->height); int32 descriptionHeight = qMin(_description.countHeight(_maxw), st::normalFont->height);
_minh = st::msgFileSize; _minh = st::msgFileSize;
@ -989,13 +989,13 @@ void Article::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0); int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto }; TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->getLayoutTitle()), titleOpts); _title.setText(st::semiboldTextStyle, textOneLine(_result->getLayoutTitle()), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height); int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = (_withThumb || _url) ? 2 : 3; int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
QString description = _result->getLayoutDescription(); QString description = _result->getLayoutDescription();
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto }; TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, description, descriptionOpts); _description.setText(st::defaultTextStyle, description, descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height); int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = titleHeight + descriptionHeight; _minh = titleHeight + descriptionHeight;
@ -1028,14 +1028,14 @@ void Article::paint(Painter &p, const QRect &clip, const PaintContext *context)
ImagePtr thumb = getResultThumb(); ImagePtr thumb = getResultThumb();
if (thumb->isNull() && !_thumbLetter.isEmpty()) { if (thumb->isNull() && !_thumbLetter.isEmpty()) {
int32 index = (_thumbLetter.at(0).unicode() % 4); int32 index = (_thumbLetter.at(0).unicode() % 4);
const style::color *colors[] = { style::color colors[] = {
&st::msgFile3Bg, st::msgFile3Bg,
&st::msgFile4Bg, st::msgFile4Bg,
&st::msgFile2Bg, st::msgFile2Bg,
&st::msgFile1Bg st::msgFile1Bg
}; };
p.fillRect(rthumb, *colors[index]); p.fillRect(rthumb, colors[index]);
if (!_thumbLetter.isEmpty()) { if (!_thumbLetter.isEmpty()) {
p.setFont(st::linksLetterFont); p.setFont(st::linksLetterFont);
p.setPen(st::linksLetterFg); p.setPen(st::linksLetterFg);
@ -1157,13 +1157,13 @@ void Game::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip); int32 textWidth = _maxw - (st::inlineThumbSize + st::inlineThumbSkip);
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto }; TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->getLayoutTitle()), titleOpts); _title.setText(st::semiboldTextStyle, textOneLine(_result->getLayoutTitle()), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height); int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = 2; int32 descriptionLines = 2;
QString description = _result->getLayoutDescription(); QString description = _result->getLayoutDescription();
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto }; TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, description, descriptionOpts); _description.setText(st::defaultTextStyle, description, descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height); int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = titleHeight + descriptionHeight; _minh = titleHeight + descriptionHeight;

View file

@ -44,31 +44,40 @@ introPhotoIconPosition: point(23px, 25px);
introPhotoTop: 10px; introPhotoTop: 10px;
introCoverTitle: FlatLabel(defaultFlatLabel) { introCoverTitle: FlatLabel(defaultFlatLabel) {
font: font(22px semibold);
textFg: introTitleFg; textFg: introTitleFg;
align: align(center); align: align(center);
style: TextStyle(defaultTextStyle) {
font: font(22px semibold);
linkFont: font(22px semibold);
linkFontOver: font(22px semibold underline);
}
} }
introCoverTitleTop: 136px; introCoverTitleTop: 136px;
introCoverDescription: FlatLabel(defaultFlatLabel) { introCoverDescription: FlatLabel(defaultFlatLabel) {
font: font(15px);
textFg: introDescriptionFg; textFg: introDescriptionFg;
align: align(center); align: align(center);
} style: TextStyle(defaultTextStyle) {
introCoverDescriptionTextStyle: TextStyle(defaultTextStyle) { font: font(15px);
lineHeight: 24px; linkFont: font(15px);
linkFontOver: font(15px underline);
lineHeight: 24px;
}
} }
introCoverDescriptionTop: 174px; introCoverDescriptionTop: 174px;
introTitle: FlatLabel(defaultFlatLabel) { introTitle: FlatLabel(defaultFlatLabel) {
font: font(17px semibold);
textFg: introTitleFg; textFg: introTitleFg;
style: TextStyle(defaultTextStyle) {
font: font(17px semibold);
linkFont: font(17px semibold);
linkFontOver: font(17px semibold underline);
}
} }
introTitleTop: 1px; introTitleTop: 1px;
introDescription: FlatLabel(defaultFlatLabel) { introDescription: FlatLabel(defaultFlatLabel) {
font: normalFont;
textFg: introDescriptionFg; textFg: introDescriptionFg;
} style: TextStyle(defaultTextStyle) {
introDescriptionTextStyle: TextStyle(defaultTextStyle) { lineHeight: 20px;
lineHeight: 20px; }
} }
introDescriptionTop: 34px; introDescriptionTop: 34px;
@ -119,7 +128,6 @@ introPasswordHintTop: 151px;
introPasswordHint: FlatLabel(introDescription) { introPasswordHint: FlatLabel(introDescription) {
textFg: windowFg; textFg: windowFg;
} }
introPasswordHintTextStyle: introDescriptionTextStyle;
introResetButton: RoundButton(defaultLightButton) { introResetButton: RoundButton(defaultLightButton) {
textFg: attentionButtonFg; textFg: attentionButtonFg;
@ -141,11 +149,11 @@ introErrorTop: 235px;
introErrorBelowLinkTop: 220px; introErrorBelowLinkTop: 220px;
introErrorDuration: 200; introErrorDuration: 200;
introError: introDescription; introError: FlatLabel(introDescription) {
}
introErrorCentered: FlatLabel(introError) { introErrorCentered: FlatLabel(introError) {
align: align(center); align: align(center);
} }
introErrorTextStyle: introDescriptionTextStyle;
introBackButton: IconButton(defaultIconButton) { introBackButton: IconButton(defaultIconButton) {
width: 56px; width: 56px;

View file

@ -87,7 +87,7 @@ CodeWidget::CodeWidget(QWidget *parent, Widget::Data *data) : Step(parent, data)
, _callTimer(this) , _callTimer(this)
, _callStatus(getData()->callStatus) , _callStatus(getData()->callStatus)
, _callTimeout(getData()->callTimeout) , _callTimeout(getData()->callTimeout)
, _callLabel(this, st::introDescription, st::introDescriptionTextStyle) , _callLabel(this, st::introDescription)
, _checkRequest(this) { , _checkRequest(this) {
connect(_code, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_code, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_callTimer, SIGNAL(timeout()), this, SLOT(onSendCall())); connect(_callTimer, SIGNAL(timeout()), this, SLOT(onSendCall()));
@ -153,7 +153,7 @@ void CodeWidget::showCodeError(const QString &text) {
} }
void CodeWidget::setInnerFocus() { void CodeWidget::setInnerFocus() {
_code->setFocus(); _code->setFocusFast();
} }
void CodeWidget::activate() { void CodeWidget::activate() {

View file

@ -90,7 +90,7 @@ void PhoneWidget::showSignup() {
showPhoneError(lang(lng_bad_phone_noreg)); showPhoneError(lang(lng_bad_phone_noreg));
if (!_signup) { if (!_signup) {
auto signupText = lng_phone_notreg(lt_link_start, textcmdStartLink(1), lt_link_end, textcmdStopLink(), lt_signup_start, textcmdStartLink(2), lt_signup_end, textcmdStopLink()); auto signupText = lng_phone_notreg(lt_link_start, textcmdStartLink(1), lt_link_end, textcmdStopLink(), lt_signup_start, textcmdStartLink(2), lt_signup_end, textcmdStopLink());
auto inner = object_ptr<Ui::FlatLabel>(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription, st::introDescriptionTextStyle); auto inner = object_ptr<Ui::FlatLabel>(this, signupText, Ui::FlatLabel::InitType::Rich, st::introDescription);
_signup.create(this, std_::move(inner), st::introErrorDuration); _signup.create(this, std_::move(inner), st::introErrorDuration);
_signup->entity()->setLink(1, MakeShared<UrlClickHandler>(qsl("https://telegram.org"), false)); _signup->entity()->setLink(1, MakeShared<UrlClickHandler>(qsl("https://telegram.org"), false));
_signup->entity()->setLink(2, MakeShared<LambdaClickHandler>([this] { _signup->entity()->setLink(2, MakeShared<LambdaClickHandler>([this] {
@ -231,7 +231,7 @@ void PhoneWidget::selectCountry(const QString &c) {
} }
void PhoneWidget::setInnerFocus() { void PhoneWidget::setInnerFocus() {
_phone->setFocus(); _phone->setFocusFast();
} }
void PhoneWidget::activate() { void PhoneWidget::activate() {

View file

@ -39,7 +39,7 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren
, _hasRecovery(getData()->hasRecovery) , _hasRecovery(getData()->hasRecovery)
, _hint(getData()->pwdHint) , _hint(getData()->pwdHint)
, _pwdField(this, st::introPassword, lang(lng_signin_password)) , _pwdField(this, st::introPassword, lang(lng_signin_password))
, _pwdHint(this, st::introPasswordHint, st::introPasswordHintTextStyle) , _pwdHint(this, st::introPasswordHint)
, _codeField(this, st::introPassword, lang(lng_signin_code)) , _codeField(this, st::introPassword, lang(lng_signin_code))
, _toRecover(this, lang(lng_signin_recover)) , _toRecover(this, lang(lng_signin_recover))
, _toPassword(this, lang(lng_signin_try_password)) , _toPassword(this, lang(lng_signin_try_password))
@ -77,9 +77,9 @@ void PwdCheckWidget::resizeEvent(QResizeEvent *e) {
void PwdCheckWidget::setInnerFocus() { void PwdCheckWidget::setInnerFocus() {
if (_pwdField->isHidden()) { if (_pwdField->isHidden()) {
_codeField->setFocus(); _codeField->setFocusFast();
} else { } else {
_pwdField->setFocus(); _pwdField->setFocusFast();
} }
} }

View file

@ -105,9 +105,9 @@ void SignupWidget::resizeEvent(QResizeEvent *e) {
void SignupWidget::setInnerFocus() { void SignupWidget::setInnerFocus() {
if (_invertOrder || _last->hasFocus()) { if (_invertOrder || _last->hasFocus()) {
_last->setFocus(); _last->setFocusFast();
} else { } else {
_first->setFocus(); _first->setFocusFast();
} }
} }

View file

@ -647,8 +647,7 @@ void Widget::Step::showError(const QString &text) {
if (_error) _error->hideAnimated(); if (_error) _error->hideAnimated();
} else { } else {
if (!_error) { if (!_error) {
auto &st = _errorCentered ? st::introErrorCentered : st::introError; _error.create(this, object_ptr<Ui::FlatLabel>(this, _errorCentered ? st::introErrorCentered : st::introError), st::introErrorDuration);
_error.create(this, object_ptr<Ui::FlatLabel>(this, st, st::introErrorTextStyle), st::introErrorDuration);
_error->hideFast(); _error->hideFast();
} }
_error->entity()->setText(text); _error->entity()->setText(text);
@ -660,12 +659,13 @@ void Widget::Step::showError(const QString &text) {
Widget::Step::Step(QWidget *parent, Data *data, bool hasCover) : TWidget(parent) Widget::Step::Step(QWidget *parent, Data *data, bool hasCover) : TWidget(parent)
, _data(data) , _data(data)
, _hasCover(hasCover) , _hasCover(hasCover)
, _title(this, _hasCover ? st::introCoverTitle : st::introTitle, st::defaultTextStyle) , _title(this, _hasCover ? st::introCoverTitle : st::introTitle)
, _description(this, object_ptr<Ui::FlatLabel>(this, _hasCover ? st::introCoverDescription : st::introDescription, _hasCover ? st::introCoverDescriptionTextStyle : st::introDescriptionTextStyle), st::introErrorDuration) { , _description(this, object_ptr<Ui::FlatLabel>(this, _hasCover ? st::introCoverDescription : st::introDescription), st::introErrorDuration) {
hide(); hide();
} }
void Widget::Step::prepareShowAnimated(Step *after) { void Widget::Step::prepareShowAnimated(Step *after) {
setInnerFocus();
if (hasCover() || after->hasCover()) { if (hasCover() || after->hasCover()) {
_coverAnimation = prepareCoverAnimation(after); _coverAnimation = prepareCoverAnimation(after);
prepareCoverMask(); prepareCoverMask();

View file

@ -383,16 +383,6 @@ bool LayerStackWidget::layerShown() const {
void LayerStackWidget::setCacheImages() { void LayerStackWidget::setCacheImages() {
auto bodyCache = QPixmap(), mainMenuCache = QPixmap(); auto bodyCache = QPixmap(), mainMenuCache = QPixmap();
if (isAncestorOf(App::wnd()->focusWidget())) {
setFocus();
}
if (_mainMenu) {
setAttribute(Qt::WA_OpaquePaintEvent, false);
hideChildren();
bodyCache = myGrab(App::wnd()->bodyWidget());
showChildren();
mainMenuCache = Ui::Shadow::grab(_mainMenu, st::boxRoundShadow, Ui::Shadow::Side::Right);
}
auto specialLayerCache = QPixmap(); auto specialLayerCache = QPixmap();
if (_specialLayer) { if (_specialLayer) {
auto sides = Ui::Shadow::Side::Left | Ui::Shadow::Side::Right; auto sides = Ui::Shadow::Side::Left | Ui::Shadow::Side::Right;
@ -408,6 +398,16 @@ void LayerStackWidget::setCacheImages() {
if (auto layer = currentLayer()) { if (auto layer = currentLayer()) {
layerCache = Ui::Shadow::grab(layer, st::boxRoundShadow); layerCache = Ui::Shadow::grab(layer, st::boxRoundShadow);
} }
if (isAncestorOf(App::wnd()->focusWidget())) {
setFocus();
}
if (_mainMenu) {
setAttribute(Qt::WA_OpaquePaintEvent, false);
hideChildren();
bodyCache = myGrab(App::wnd()->bodyWidget());
showChildren();
mainMenuCache = Ui::Shadow::grab(_mainMenu, st::boxRoundShadow, Ui::Shadow::Side::Right);
}
setAttribute(Qt::WA_OpaquePaintEvent, !bodyCache.isNull()); setAttribute(Qt::WA_OpaquePaintEvent, !bodyCache.isNull());
updateLayerBoxes(); updateLayerBoxes();
_background->setCacheImages(std_::move(bodyCache), std_::move(mainMenuCache), std_::move(specialLayerCache), std_::move(layerCache)); _background->setCacheImages(std_::move(bodyCache), std_::move(mainMenuCache), std_::move(specialLayerCache), std_::move(layerCache));

View file

@ -210,44 +210,44 @@ int32 documentColorIndex(DocumentData *document, QString &ext) {
return colorIndex; return colorIndex;
} }
const style::color &documentColor(int32 colorIndex) { style::color documentColor(int32 colorIndex) {
static const style::color *colors[] = { const style::color colors[] = {
&st::msgFile1Bg, st::msgFile1Bg,
&st::msgFile2Bg, st::msgFile2Bg,
&st::msgFile3Bg, st::msgFile3Bg,
&st::msgFile4Bg st::msgFile4Bg
}; };
return *colors[colorIndex & 3]; return colors[colorIndex & 3];
} }
const style::color &documentDarkColor(int32 colorIndex) { style::color documentDarkColor(int32 colorIndex) {
static const style::color *colors[] = { static style::color colors[] = {
&st::msgFile1BgDark, st::msgFile1BgDark,
&st::msgFile2BgDark, st::msgFile2BgDark,
&st::msgFile3BgDark, st::msgFile3BgDark,
&st::msgFile4BgDark st::msgFile4BgDark
}; };
return *colors[colorIndex & 3]; return colors[colorIndex & 3];
} }
const style::color &documentOverColor(int32 colorIndex) { style::color documentOverColor(int32 colorIndex) {
static const style::color *colors[] = { static style::color colors[] = {
&st::msgFile1BgOver, st::msgFile1BgOver,
&st::msgFile2BgOver, st::msgFile2BgOver,
&st::msgFile3BgOver, st::msgFile3BgOver,
&st::msgFile4BgOver st::msgFile4BgOver
}; };
return *colors[colorIndex & 3]; return colors[colorIndex & 3];
} }
const style::color &documentSelectedColor(int32 colorIndex) { style::color documentSelectedColor(int32 colorIndex) {
static const style::color *colors[] = { static style::color colors[] = {
&st::msgFile1BgSelected, st::msgFile1BgSelected,
&st::msgFile2BgSelected, st::msgFile2BgSelected,
&st::msgFile3BgSelected, st::msgFile3BgSelected,
&st::msgFile4BgSelected st::msgFile4BgSelected
}; };
return *colors[colorIndex & 3]; return colors[colorIndex & 3];
} }
RoundCorners documentCorners(int32 colorIndex) { RoundCorners documentCorners(int32 colorIndex) {

View file

@ -84,10 +84,10 @@ QString formatPlayedText(qint64 played, qint64 duration);
QString documentName(DocumentData *document); QString documentName(DocumentData *document);
TextWithEntities documentNameWithEntities(DocumentData *document); TextWithEntities documentNameWithEntities(DocumentData *document);
int32 documentColorIndex(DocumentData *document, QString &ext); int32 documentColorIndex(DocumentData *document, QString &ext);
const style::color &documentColor(int colorIndex); style::color documentColor(int colorIndex);
const style::color &documentDarkColor(int colorIndex); style::color documentDarkColor(int colorIndex);
const style::color &documentOverColor(int colorIndex); style::color documentOverColor(int colorIndex);
const style::color &documentSelectedColor(int colorIndex); style::color documentSelectedColor(int colorIndex);
RoundCorners documentCorners(int colorIndex); RoundCorners documentCorners(int colorIndex);
bool documentIsValidMediaFile(const QString &filepath); bool documentIsValidMediaFile(const QString &filepath);

View file

@ -299,8 +299,8 @@ void MainWidget::updateForwardingTexts() {
text = lng_forward_messages(lt_count, _toForward.size()); text = lng_forward_messages(lt_count, _toForward.size());
} }
} }
_toForwardFrom.setText(st::msgServiceNameFont, from, _textNameOptions); _toForwardFrom.setText(st::msgNameStyle, from, _textNameOptions);
_toForwardText.setText(st::msgFont, textClean(text), _textDlgOptions); _toForwardText.setText(st::messageTextStyle, textClean(text), _textDlgOptions);
_toForwardNameVersion = version; _toForwardNameVersion = version;
} }
@ -1087,7 +1087,7 @@ void MainWidget::onCacheBackground() {
_cachedBackground = App::pixmapFromImageInPlace(std_::move(result)); _cachedBackground = App::pixmapFromImageInPlace(std_::move(result));
} else { } else {
QRect to, from; QRect to, from;
backgroundParams(_willCacheFor, to, from); Window::Theme::ComputeBackgroundRects(_willCacheFor, bg.size(), to, from);
_cachedX = to.x(); _cachedX = to.x();
_cachedY = to.y(); _cachedY = to.y();
_cachedBackground = App::pixmapFromImageInPlace(bg.toImage().copy(from).scaled(to.width() * cIntRetinaFactor(), to.height() * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); _cachedBackground = App::pixmapFromImageInPlace(bg.toImage().copy(from).scaled(to.width() * cIntRetinaFactor(), to.height() * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
@ -1854,31 +1854,6 @@ QPixmap MainWidget::cachedBackground(const QRect &forRect, int &x, int &y) {
return QPixmap(); return QPixmap();
} }
void MainWidget::backgroundParams(const QRect &forRect, QRect &to, QRect &from) const {
auto bg = Window::Theme::Background()->image().size();
if (uint64(bg.width()) * forRect.height() > uint64(bg.height()) * forRect.width()) {
float64 pxsize = forRect.height() / float64(bg.height());
int takewidth = qCeil(forRect.width() / pxsize);
if (takewidth > bg.width()) {
takewidth = bg.width();
} else if ((bg.width() % 2) != (takewidth % 2)) {
++takewidth;
}
to = QRect(int((forRect.width() - takewidth * pxsize) / 2.), 0, qCeil(takewidth * pxsize), forRect.height());
from = QRect((bg.width() - takewidth) / 2, 0, takewidth, bg.height());
} else {
float64 pxsize = forRect.width() / float64(bg.width());
int takeheight = qCeil(forRect.height() / pxsize);
if (takeheight > bg.height()) {
takeheight = bg.height();
} else if ((bg.height() % 2) != (takeheight % 2)) {
++takeheight;
}
to = QRect(0, int((forRect.height() - takeheight * pxsize) / 2.), forRect.width(), qCeil(takeheight * pxsize));
from = QRect(0, (bg.height() - takeheight) / 2, bg.width(), takeheight);
}
}
void MainWidget::updateScrollColors() { void MainWidget::updateScrollColors() {
_history->updateScrollColors(); _history->updateScrollColors();
} }

View file

@ -316,7 +316,6 @@ public:
bool isIdle() const; bool isIdle() const;
QPixmap cachedBackground(const QRect &forRect, int &x, int &y); QPixmap cachedBackground(const QRect &forRect, int &x, int &y);
void backgroundParams(const QRect &forRect, QRect &to, QRect &from) const;
void updateScrollColors(); void updateScrollColors();
void setChatBackground(const App::WallPaper &wp); void setChatBackground(const App::WallPaper &wp);

View file

@ -262,6 +262,7 @@ void MainWindow::setupPasscode() {
updateControlsGeometry(); updateControlsGeometry();
if (_main) _main->hide(); if (_main) _main->hide();
_mediaView->hide();
Ui::hideSettingsAndLayer(true); Ui::hideSettingsAndLayer(true);
if (_intro) _intro->hide(); if (_intro) _intro->hide();
if (animated) { if (animated) {
@ -1291,7 +1292,7 @@ QImage MainWindow::iconLarge() const {
return iconbig256; return iconbig256;
} }
void MainWindow::placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) { void MainWindow::placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) {
QPainter p(&img); QPainter p(&img);
QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0')); QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 10, 1, 10, QChar('0'));
@ -1329,7 +1330,7 @@ void MainWindow::placeSmallCounter(QImage &img, int size, int count, const style
} }
QImage MainWindow::iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) { QImage MainWindow::iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) {
bool layer = false; bool layer = false;
if (size < 0) { if (size < 0) {
size = -size; size = -size;

View file

@ -144,7 +144,7 @@ public:
bool isActive(bool cached = true) const; bool isActive(bool cached = true) const;
void hideMediaview(); void hideMediaview();
QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) override; QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
bool contentOverlapped(const QRect &globalRect); bool contentOverlapped(const QRect &globalRect);
bool contentOverlapped(QWidget *w, QPaintEvent *e) { bool contentOverlapped(QWidget *w, QPaintEvent *e) {
@ -226,7 +226,7 @@ private:
QPixmap grabInner(); QPixmap grabInner();
void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) override; void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) override;
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64; QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;
struct DelayedServiceMsg { struct DelayedServiceMsg {

View file

@ -54,7 +54,6 @@ mediaPlayerCloseRight: 0px;
mediaPlayerName: FlatLabel(defaultFlatLabel) { mediaPlayerName: FlatLabel(defaultFlatLabel) {
maxHeight: 20px; maxHeight: 20px;
textFg: windowFg;
} }
mediaPlayerTime: LabelSimple(defaultLabelSimple) { mediaPlayerTime: LabelSimple(defaultLabelSimple) {
textFg: windowSubTextFg; textFg: windowSubTextFg;

View file

@ -229,7 +229,7 @@ void CoverWidget::updatePlayPrevNextPositions() {
} }
void CoverWidget::updateLabelPositions() { void CoverWidget::updateLabelPositions() {
_nameLabel->moveToLeft(st::mediaPlayerPanelPadding, st::mediaPlayerPanelNameTop - st::mediaPlayerName.font->ascent); _nameLabel->moveToLeft(st::mediaPlayerPanelPadding, st::mediaPlayerPanelNameTop - st::mediaPlayerName.style.font->ascent);
_timeLabel->moveToRight(st::mediaPlayerPanelPadding, st::mediaPlayerPanelNameTop - st::mediaPlayerTime.font->ascent); _timeLabel->moveToRight(st::mediaPlayerPanelPadding, st::mediaPlayerPanelNameTop - st::mediaPlayerTime.font->ascent);
} }

View file

@ -301,7 +301,7 @@ void Widget::updateLabelsGeometry() {
widthForName -= _timeLabel->width() + 2 * st::normalFont->spacew; widthForName -= _timeLabel->width() + 2 * st::normalFont->spacew;
_nameLabel->resizeToWidth(widthForName); _nameLabel->resizeToWidth(widthForName);
_nameLabel->moveToLeft(left, st::mediaPlayerNameTop - st::mediaPlayerName.font->ascent); _nameLabel->moveToLeft(left, st::mediaPlayerNameTop - st::mediaPlayerName.style.font->ascent);
_timeLabel->moveToRight(right, st::mediaPlayerNameTop - st::mediaPlayerTime.font->ascent); _timeLabel->moveToRight(right, st::mediaPlayerNameTop - st::mediaPlayerTime.font->ascent);
} }

View file

@ -81,13 +81,13 @@ void Controller::handleSeekFinished(float64 progress) {
void Controller::showAnimated() { void Controller::showAnimated() {
startFading([this]() { startFading([this]() {
_fadeAnimation->fadeIn(st::mvShowDuration); _fadeAnimation->fadeIn(st::mediaviewShowDuration);
}); });
} }
void Controller::hideAnimated() { void Controller::hideAnimated() {
startFading([this]() { startFading([this]() {
_fadeAnimation->fadeOut(st::mvHideDuration); _fadeAnimation->fadeOut(st::mediaviewHideDuration);
}); });
} }

View file

@ -150,3 +150,70 @@ mediaviewDropdownMenu: DropdownMenu(defaultDropdownMenu) {
shadow: mediaviewMenuShadow; shadow: mediaviewMenuShadow;
} }
} }
mediaviewSaveMsgCheck: icon {{ "mediaview_save_check", mediaviewSaveMsgFg }};
mediaviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
mediaviewSaveMsgCheckPos: point(23px, 21px);
mediaviewSaveMsgShowing: 200;
mediaviewSaveMsgShown: 2000;
mediaviewSaveMsgHiding: 2500;
mediaviewSaveMsgStyle: TextStyle(defaultTextStyle) {
font: font(16px);
linkFont: font(16px);
linkFontOver: font(16px underline);
}
mediaviewTextPalette: TextPalette(defaultTextPalette) {
linkFg: mediaviewTextLinkFg;
}
mediaviewCaptionStyle: defaultTextStyle;
mediaviewThickFont: semiboldFont;
mediaviewFont: normalFont;
mediaviewTextStyle: defaultTextStyle;
mediaviewTextLeft: 16px;
mediaviewTextSkip: 10px;
mediaviewHeaderTop: 48px;
mediaviewTextTop: 24px;
mediaviewTextOpacity: 0.5;
mediaviewTextOverOpacity: 1;
mediaviewIconOpacity: 0.45;
mediaviewIconOverOpacity: 1;
mediaviewControlBgOpacity: 0.3;
mediaviewControlMargin: 0px;
mediaviewControlSize: 90px;
mediaviewIconSize: size(60px, 56px);
mediaviewWaitHide: 2000;
mediaviewHideDuration: 1000;
mediaviewShowDuration: 200;
mediaviewFadeDuration: 150;
mediaviewDeltaFromLastAction: 5px;
mediaviewSwipeDistance: 80px;
mediaviewCaptionPadding: margins(18px, 10px, 18px, 10px);
mediaviewCaptionMargin: size(11px, 11px);
mediaviewCaptionRadius: 2px;
themePreviewSize: size(903px, 584px);
themePreviewBg: windowBg;
themePreviewOverlayOpacity: 0.7;
themePreviewMargin: margins(36px, 52px, 36px, 88px);
themePreviewTitleTop: 14px;
themePreviewTitleFg: windowBoldFg;
themePreviewTitleFont: font(17px semibold);
themePreviewLoadingFont: font(16px);
themePreviewLoadingFg: windowSubTextFg;
themePreviewApplyButton: RoundButton(defaultActiveButton) {
height: 38px;
font: font(15px semibold);
}
themePreviewCancelButton: RoundButton(defaultLightButton) {
height: 38px;
font: font(15px semibold);
}
themePreviewButtonsSkip: 20px;
themePreviewDialogsWidth: 312px;

View file

@ -34,6 +34,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "styles/style_history.h" #include "styles/style_history.h"
#include "media/media_audio.h" #include "media/media_audio.h"
#include "history/history_media_types.h" #include "history/history_media_types.h"
#include "window/window_theme_preview.h"
#include "core/task_queue.h"
namespace { namespace {
@ -71,13 +73,13 @@ MediaView::MediaView() : TWidget(App::wnd())
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink) , _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
, _docCancel(this, lang(lng_cancel), st::mediaviewFileLink) , _docCancel(this, lang(lng_cancel), st::mediaviewFileLink)
, _radial(animation(this, &MediaView::step_radial)) , _radial(animation(this, &MediaView::step_radial))
, _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction) , _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
, _a_state(animation(this, &MediaView::step_state)) , _a_state(animation(this, &MediaView::step_state))
, _dropdown(this, st::mediaviewDropdownMenu) { , _dropdown(this, st::mediaviewDropdownMenu) {
TextCustomTagsMap custom; TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
_saveMsgText.setRichText(st::medviewSaveMsgFont, lang(lng_mediaview_saved), _textDlgOptions, custom); _saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom);
_saveMsg = QRect(0, 0, _saveMsgText.maxWidth() + st::medviewSaveMsgPadding.left() + st::medviewSaveMsgPadding.right(), st::medviewSaveMsgFont->height + st::medviewSaveMsgPadding.top() + st::medviewSaveMsgPadding.bottom()); _saveMsg = QRect(0, 0, _saveMsgText.maxWidth() + st::mediaviewSaveMsgPadding.left() + st::mediaviewSaveMsgPadding.right(), st::mediaviewSaveMsgStyle.font->height + st::mediaviewSaveMsgPadding.top() + st::mediaviewSaveMsgPadding.bottom());
_saveMsgText.setLink(1, MakeShared<LambdaClickHandler>([this] { showSaveMsgFile(); })); _saveMsgText.setLink(1, MakeShared<LambdaClickHandler>([this] { showSaveMsgFile(); }));
connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int))); connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int)));
@ -132,12 +134,12 @@ void MediaView::moveToScreen() {
setGeometry(avail); setGeometry(avail);
} }
int32 navSkip = 2 * st::mvControlMargin + st::mvControlSize; int32 navSkip = 2 * st::mediaviewControlMargin + st::mediaviewControlSize;
_closeNav = myrtlrect(width() - st::mvControlMargin - st::mvControlSize, st::mvControlMargin, st::mvControlSize, st::mvControlSize); _closeNav = myrtlrect(width() - st::mediaviewControlMargin - st::mediaviewControlSize, st::mediaviewControlMargin, st::mediaviewControlSize, st::mediaviewControlSize);
_closeNavIcon = centerrect(_closeNav, st::mediaviewClose); _closeNavIcon = centerrect(_closeNav, st::mediaviewClose);
_leftNav = myrtlrect(st::mvControlMargin, navSkip, st::mvControlSize, height() - 2 * navSkip); _leftNav = myrtlrect(st::mediaviewControlMargin, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
_leftNavIcon = centerrect(_leftNav, st::mediaviewLeft); _leftNavIcon = centerrect(_leftNav, st::mediaviewLeft);
_rightNav = myrtlrect(width() - st::mvControlMargin - st::mvControlSize, navSkip, st::mvControlSize, height() - 2 * navSkip); _rightNav = myrtlrect(width() - st::mediaviewControlMargin - st::mediaviewControlSize, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
_rightNavIcon = centerrect(_rightNav, st::mediaviewRight); _rightNavIcon = centerrect(_rightNav, st::mediaviewRight);
_saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2); _saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2);
@ -194,6 +196,10 @@ bool MediaView::fileShown() const {
return !_current.isNull() || gifShown(); return !_current.isNull() || gifShown();
} }
bool MediaView::fileBubbleShown() const {
return _doc && !fileShown() && !_themePreviewShown;
}
bool MediaView::gifShown() const { bool MediaView::gifShown() const {
if (_gif && _gif->ready()) { if (_gif && _gif->ready()) {
if (!_gif->started()) { if (!_gif->started()) {
@ -220,7 +226,7 @@ void MediaView::stopGif() {
} }
void MediaView::documentUpdated(DocumentData *doc) { void MediaView::documentUpdated(DocumentData *doc) {
if (_doc && _doc == doc && !fileShown()) { if (fileBubbleShown() && _doc == doc) {
if ((_doc->loading() && _docCancel->isHidden()) || (!_doc->loading() && !_docCancel->isHidden())) { if ((_doc->loading() && _docCancel->isHidden()) || (!_doc->loading() && !_docCancel->isHidden())) {
updateControls(); updateControls();
} else if (_doc->loading()) { } else if (_doc->loading()) {
@ -238,7 +244,7 @@ void MediaView::changingMsgId(HistoryItem *row, MsgId newId) {
} }
void MediaView::updateDocSize() { void MediaView::updateDocSize() {
if (!_doc || fileShown()) return; if (!fileBubbleShown()) return;
if (_doc->loading()) { if (_doc->loading()) {
quint64 ready = _doc->loadOffset(), total = _doc->size; quint64 ready = _doc->loadOffset(), total = _doc->size;
@ -262,16 +268,16 @@ void MediaView::updateDocSize() {
} else { } else {
_docSize = formatSizeText(_doc->size); _docSize = formatSizeText(_doc->size);
} }
_docSizeWidth = st::mvFont->width(_docSize); _docSizeWidth = st::mediaviewFont->width(_docSize);
int32 maxw = st::mediaviewFileSize.width() - st::mediaviewFileIconSize - st::mediaviewFilePadding * 3; int32 maxw = st::mediaviewFileSize.width() - st::mediaviewFileIconSize - st::mediaviewFilePadding * 3;
if (_docSizeWidth > maxw) { if (_docSizeWidth > maxw) {
_docSize = st::mvFont->elided(_docSize, maxw); _docSize = st::mediaviewFont->elided(_docSize, maxw);
_docSizeWidth = st::mvFont->width(_docSize); _docSizeWidth = st::mediaviewFont->width(_docSize);
} }
} }
void MediaView::updateControls() { void MediaView::updateControls() {
if (_doc && !fileShown()) { if (fileBubbleShown()) {
if (_doc->loading()) { if (_doc->loading()) {
_docDownload->hide(); _docDownload->hide();
_docSaveAs->hide(); _docSaveAs->hide();
@ -299,10 +305,12 @@ void MediaView::updateControls() {
} }
radialStart(); radialStart();
updateThemePreviewGeometry();
_saveVisible = ((_photo && _photo->loaded()) || (_doc && (_doc->loaded(DocumentData::FilePathResolveChecked) || (!fileShown() && (_photo || _doc))))); _saveVisible = ((_photo && _photo->loaded()) || (_doc && (_doc->loaded(DocumentData::FilePathResolveChecked) || (!fileShown() && (_photo || _doc)))));
_saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height()); _saveNav = myrtlrect(width() - st::mediaviewIconSize.width() * 2, height() - st::mediaviewIconSize.height(), st::mediaviewIconSize.width(), st::mediaviewIconSize.height());
_saveNavIcon = centerrect(_saveNav, st::mediaviewSave); _saveNavIcon = centerrect(_saveNav, st::mediaviewSave);
_moreNav = myrtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height()); _moreNav = myrtlrect(width() - st::mediaviewIconSize.width(), height() - st::mediaviewIconSize.height(), st::mediaviewIconSize.width(), st::mediaviewIconSize.height());
_moreNavIcon = centerrect(_moreNav, st::mediaviewMore); _moreNavIcon = centerrect(_moreNav, st::mediaviewMore);
QDateTime d, dNow(date(unixtime())); QDateTime d, dNow(date(unixtime()));
@ -321,12 +329,12 @@ void MediaView::updateControls() {
_dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat())); _dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat()));
} }
if (_from) { if (_from) {
_fromName.setText(st::mvFont, (_from->migrateTo() ? _from->migrateTo() : _from)->name, _textNameOptions); _fromName.setText(st::mediaviewTextStyle, (_from->migrateTo() ? _from->migrateTo() : _from)->name, _textNameOptions);
_nameNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height); _nameNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mediaviewFont->height);
_dateNav = myrtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height); _dateNav = myrtlrect(st::mediaviewTextLeft + _nameNav.width() + st::mediaviewTextSkip, height() - st::mediaviewTextTop, st::mediaviewFont->width(_dateText), st::mediaviewFont->height);
} else { } else {
_nameNav = QRect(); _nameNav = QRect();
_dateNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height); _dateNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewTextTop, st::mediaviewFont->width(_dateText), st::mediaviewFont->height);
} }
updateHeader(); updateHeader();
if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewChatPhotos || _overview == OverviewFiles || _overview == OverviewVideos))) { if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewChatPhotos || _overview == OverviewFiles || _overview == OverviewVideos))) {
@ -354,9 +362,9 @@ void MediaView::updateControls() {
if (!_caption.isEmpty()) { if (!_caption.isEmpty()) {
int32 skipw = qMax(_dateNav.left() + _dateNav.width(), _headerNav.left() + _headerNav.width()); int32 skipw = qMax(_dateNav.left() + _dateNav.width(), _headerNav.left() + _headerNav.width());
int32 maxw = qMin(qMax(width() - 2 * skipw - st::mvCaptionPadding.left() - st::mvCaptionPadding.right() - 2 * st::mvCaptionMargin.width(), int(st::msgMinWidth)), _caption.maxWidth()); int32 maxw = qMin(qMax(width() - 2 * skipw - st::mediaviewCaptionPadding.left() - st::mediaviewCaptionPadding.right() - 2 * st::mediaviewCaptionMargin.width(), int(st::msgMinWidth)), _caption.maxWidth());
int32 maxh = qMin(_caption.countHeight(maxw), int(height() / 4 - st::mvCaptionPadding.top() - st::mvCaptionPadding.bottom() - 2 * st::mvCaptionMargin.height())); int32 maxh = qMin(_caption.countHeight(maxw), int(height() / 4 - st::mediaviewCaptionPadding.top() - st::mediaviewCaptionPadding.bottom() - 2 * st::mediaviewCaptionMargin.height()));
_captionRect = QRect((width() - maxw) / 2, height() - maxh - st::mvCaptionPadding.bottom() - st::mvCaptionMargin.height(), maxw, maxh); _captionRect = QRect((width() - maxw) / 2, height() - maxh - st::mediaviewCaptionPadding.bottom() - st::mediaviewCaptionMargin.height(), maxw, maxh);
} else { } else {
_captionRect = QRect(); _captionRect = QRect();
} }
@ -410,7 +418,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
case OverMore: update(_moreNav); break; case OverMore: update(_moreNav); break;
default: break; default: break;
} }
float64 dt = float64(ms - start) / st::mvFadeDuration; float64 dt = float64(ms - start) / st::mediaviewFadeDuration;
if (dt >= 1) { if (dt >= 1) {
_animOpacities.remove(i.key()); _animOpacities.remove(i.key());
i = _animations.erase(i); i = _animations.erase(i);
@ -420,7 +428,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
} }
} }
if (_controlsState == ControlsShowing || _controlsState == ControlsHiding) { if (_controlsState == ControlsShowing || _controlsState == ControlsHiding) {
float64 dt = float64(ms - _controlsAnimStarted) / (_controlsState == ControlsShowing ? st::mvShowDuration : st::mvHideDuration); float64 dt = float64(ms - _controlsAnimStarted) / (_controlsState == ControlsShowing ? st::mediaviewShowDuration : st::mediaviewHideDuration);
if (dt >= 1) { if (dt >= 1) {
a_cOpacity.finish(); a_cOpacity.finish();
_controlsState = (_controlsState == ControlsShowing ? ControlsShown : ControlsHidden); _controlsState = (_controlsState == ControlsShowing ? ControlsShown : ControlsHidden);
@ -428,7 +436,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
} else { } else {
a_cOpacity.update(dt, anim::linear); a_cOpacity.update(dt, anim::linear);
} }
QRegion toUpdate = QRegion() + (_over == OverLeftNav ? _leftNav : _leftNavIcon) + (_over == OverRightNav ? _rightNav : _rightNavIcon) + (_over == OverClose ? _closeNav : _closeNavIcon) + _saveNavIcon + _moreNavIcon + _headerNav + _nameNav + _dateNav + _captionRect.marginsAdded(st::mvCaptionPadding); QRegion toUpdate = QRegion() + (_over == OverLeftNav ? _leftNav : _leftNavIcon) + (_over == OverRightNav ? _rightNav : _rightNavIcon) + (_over == OverClose ? _closeNav : _closeNavIcon) + _saveNavIcon + _moreNavIcon + _headerNav + _nameNav + _dateNav + _captionRect.marginsAdded(st::mediaviewCaptionPadding);
update(toUpdate); update(toUpdate);
if (dt < 1) result = true; if (dt < 1) result = true;
} }
@ -500,7 +508,7 @@ void MediaView::step_radial(TimeMs ms, bool timer) {
} else { } else {
const FileLocation &location(_doc->location(true)); const FileLocation &location(_doc->location(true));
if (location.accessEnable()) { if (location.accessEnable()) {
if (_doc->isAnimation() || _doc->isVideo() || QImageReader(location.name()).canRead()) { if (_doc->isAnimation() || _doc->isVideo() || _doc->isTheme() || QImageReader(location.name()).canRead()) {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
} }
location.accessDisable(); location.accessDisable();
@ -626,7 +634,7 @@ void MediaView::close() {
void MediaView::activateControls() { void MediaView::activateControls() {
if (!_menu && !_mousePressed) { if (!_menu && !_mousePressed) {
_controlsHideTimer.start(int(st::mvWaitHide)); _controlsHideTimer.start(int(st::mediaviewWaitHide));
} }
if (_fullScreenVideo) { if (_fullScreenVideo) {
if (_clipController) { if (_clipController) {
@ -1120,6 +1128,7 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
stopGif(); stopGif();
destroyThemePreview();
_doc = nullptr; _doc = nullptr;
_fullScreenVideo = false; _fullScreenVideo = false;
_photo = photo; _photo = photo;
@ -1132,7 +1141,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
_caption = Text(); _caption = Text();
if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : nullptr) { if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : nullptr) {
if (HistoryPhoto *photoMsg = dynamic_cast<HistoryPhoto*>(itemMsg->getMedia())) { if (HistoryPhoto *photoMsg = dynamic_cast<HistoryPhoto*>(itemMsg->getMedia())) {
_caption.setMarkedText(st::mvCaptionFont, photoMsg->getCaption(), (item->author()->isUser() && item->author()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions); _caption.setMarkedText(st::mediaviewCaptionStyle, photoMsg->getCaption(), (item->author()->isUser() && item->author()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions);
} }
} }
@ -1166,14 +1175,25 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
displayFinished(); displayFinished();
} }
void MediaView::destroyThemePreview() {
_themePreviewShown = false;
_themePreview.reset();
_themeApply.destroy();
_themeCancel.destroy();
}
void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty messages shown as docs: doc can be NULL void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty messages shown as docs: doc can be NULL
if (!doc || (!doc->isAnimation() && !doc->isVideo()) || doc != _doc || (item && (item->id != _msgid || (item->history() != (_msgmigrated ? _migrated : _history))))) { auto documentChanged = (!doc || doc != _doc || (item && (item->id != _msgid || (item->history() != (_msgmigrated ? _migrated : _history)))));
if (documentChanged || (!doc->isAnimation() && !doc->isVideo())) {
_fullScreenVideo = false; _fullScreenVideo = false;
_current = QPixmap(); _current = QPixmap();
stopGif(); stopGif();
} else if (gifShown()) { } else if (gifShown()) {
_current = QPixmap(); _current = QPixmap();
} }
if (documentChanged || !doc->isTheme()) {
destroyThemePreview();
}
_doc = doc; _doc = doc;
_photo = nullptr; _photo = nullptr;
_radial.stop(); _radial.stop();
@ -1196,6 +1216,8 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (_doc->isAnimation() || _doc->isVideo()) { if (_doc->isAnimation() || _doc->isVideo()) {
initAnimation(); initAnimation();
} else if (_doc->isTheme()) {
initThemePreview();
} else { } else {
const FileLocation &location(_doc->location(true)); const FileLocation &location(_doc->location(true));
if (location.accessEnable()) { if (location.accessEnable()) {
@ -1209,10 +1231,10 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
} }
_docIconRect = QRect((width() - st::mediaviewFileIconSize) / 2, (height() - st::mediaviewFileIconSize) / 2, st::mediaviewFileIconSize, st::mediaviewFileIconSize); _docIconRect = QRect((width() - st::mediaviewFileIconSize) / 2, (height() - st::mediaviewFileIconSize) / 2, st::mediaviewFileIconSize, st::mediaviewFileIconSize);
if (!fileShown()) { if (fileBubbleShown()) {
if (!_doc || _doc->thumb->isNull()) { if (!_doc || _doc->thumb->isNull()) {
int32 colorIndex = documentColorIndex(_doc, _docExt); int32 colorIndex = documentColorIndex(_doc, _docExt);
_docIconColor = &documentColor(colorIndex); _docIconColor = documentColor(colorIndex);
const style::icon *(thumbs[]) = { &st::mediaviewFileBlue, &st::mediaviewFileGreen, &st::mediaviewFileRed, &st::mediaviewFileYellow }; const style::icon *(thumbs[]) = { &st::mediaviewFileBlue, &st::mediaviewFileGreen, &st::mediaviewFileRed, &st::mediaviewFileYellow };
_docIcon = thumbs[colorIndex]; _docIcon = thumbs[colorIndex];
@ -1255,6 +1277,8 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
_docRect = QRect((width() - st::mediaviewFileSize.width()) / 2, (height() - st::mediaviewFileSize.height()) / 2, st::mediaviewFileSize.width(), st::mediaviewFileSize.height()); _docRect = QRect((width() - st::mediaviewFileSize.width()) / 2, (height() - st::mediaviewFileSize.height()) / 2, st::mediaviewFileSize.width(), st::mediaviewFileSize.height());
_docIconRect = myrtlrect(_docRect.x() + st::mediaviewFilePadding, _docRect.y() + st::mediaviewFilePadding, st::mediaviewFileIconSize, st::mediaviewFileIconSize); _docIconRect = myrtlrect(_docRect.x() + st::mediaviewFilePadding, _docRect.y() + st::mediaviewFilePadding, st::mediaviewFileIconSize, st::mediaviewFileIconSize);
} else if (_themePreviewShown) {
updateThemePreviewGeometry();
} else if (!_current.isNull()) { } else if (!_current.isNull()) {
_current.setDevicePixelRatio(cRetinaFactor()); _current.setDevicePixelRatio(cRetinaFactor());
_w = convertScale(_current.width()); _w = convertScale(_current.width());
@ -1304,6 +1328,25 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
displayFinished(); displayFinished();
} }
void MediaView::updateThemePreviewGeometry() {
if (_themePreviewShown) {
auto previewRect = QRect((width() - st::themePreviewSize.width()) / 2, (height() - st::themePreviewSize.height()) / 2, st::themePreviewSize.width(), st::themePreviewSize.height());
_themePreviewRect = previewRect.marginsAdded(st::themePreviewMargin);
if (_themeApply) {
auto right = width() - _themePreviewRect.x() - _themePreviewRect.width() + st::themePreviewMargin.right();
_themeApply->moveToRight(right, _themePreviewRect.y() + _themePreviewRect.height() - st::themePreviewMargin.bottom() + (st::themePreviewMargin.bottom() - _themeApply->height()) / 2);
right += _themeApply->width() + st::themePreviewButtonsSkip;
_themeCancel->moveToRight(right, _themeApply->y());
}
// For context menu event.
_x = _themePreviewRect.x();
_y = _themePreviewRect.y();
_w = _themePreviewRect.width();
_h = _themePreviewRect.height();
}
}
void MediaView::displayFinished() { void MediaView::displayFinished() {
updateControls(); updateControls();
if (isHidden()) { if (isHidden()) {
@ -1363,6 +1406,59 @@ void MediaView::createClipReader() {
createClipController(); createClipController();
} }
void MediaView::initThemePreview() {
t_assert(_doc && _doc->isTheme());
auto &location = _doc->location();
if (!location.isEmpty() && location.accessEnable()) {
_themePreviewShown = true;
auto path = _doc->location().name();
auto id = _themePreviewId = rand_value<uint64>();
auto ready = base::lambda_guarded(this, [this, id](std_::unique_ptr<Window::Theme::Preview> result) {
if (id != _themePreviewId) {
return;
}
_themePreviewId = 0;
_themePreview = std_::move(result);
if (_themePreview) {
_themeApply.create(this, lang(lng_theme_preview_apply), st::themePreviewApplyButton);
_themeApply->show();
_themeApply->setClickedCallback([this] {
auto preview = std_::move(_themePreview);
close();
Window::Theme::Apply(std_::move(preview));
});
_themeCancel.create(this, lang(lng_cancel), st::themePreviewCancelButton);
_themeCancel->show();
_themeCancel->setClickedCallback([this] { close(); });
updateControls();
}
update();
});
struct mutable_ready {
mutable_ready(decltype(ready) value) : value(std_::move(value)) {
}
mutable decltype(ready) value;
};
struct mutable_result {
mutable_result(std_::unique_ptr<Window::Theme::Preview> value) : value(std_::move(value)) {
}
mutable std_::unique_ptr<Window::Theme::Preview> value;
};
Window::Theme::CurrentData current;
current.backgroundId = Window::Theme::Background()->id();
current.backgroundImage = Window::Theme::Background()->image();
current.backgroundTiled = Window::Theme::Background()->tile();
base::TaskQueue::Normal().Put([path, current, callback = mutable_ready(std_::move(ready))]() {
auto preview = Window::Theme::GeneratePreview(path, current);
base::TaskQueue::Main().Put([result = mutable_result(std_::move(preview)), callback = std_::move(callback.value)]() {
callback(std_::move(result.value));
});
});
location.accessDisable();
}
}
void MediaView::createClipController() { void MediaView::createClipController() {
if (!_doc->isVideo()) return; if (!_doc->isVideo()) return;
@ -1389,7 +1485,7 @@ void MediaView::setClipControllerGeometry() {
int controllerBottom = _captionRect.isEmpty() ? height() : _captionRect.y(); int controllerBottom = _captionRect.isEmpty() ? height() : _captionRect.y();
_clipController->setGeometry( _clipController->setGeometry(
(width() - _clipController->width()) / 2, (width() - _clipController->width()) / 2,
controllerBottom - _clipController->height() - st::mvCaptionPadding.bottom() - st::mvCaptionMargin.height(), controllerBottom - _clipController->height() - st::mediaviewCaptionPadding.bottom() - st::mediaviewCaptionMargin.height(),
st::mediaviewControllerSize.width(), st::mediaviewControllerSize.width(),
st::mediaviewControllerSize.height()); st::mediaviewControllerSize.height());
myEnsureResized(_clipController); myEnsureResized(_clipController);
@ -1603,26 +1699,26 @@ void MediaView::paintEvent(QPaintEvent *e) {
if (_saveMsgStarted) { if (_saveMsgStarted) {
auto ms = getms(); auto ms = getms();
float64 dt = float64(ms) - _saveMsgStarted, hidingDt = dt - st::medviewSaveMsgShowing - st::medviewSaveMsgShown; float64 dt = float64(ms) - _saveMsgStarted, hidingDt = dt - st::mediaviewSaveMsgShowing - st::mediaviewSaveMsgShown;
if (dt < st::medviewSaveMsgShowing + st::medviewSaveMsgShown + st::medviewSaveMsgHiding) { if (dt < st::mediaviewSaveMsgShowing + st::mediaviewSaveMsgShown + st::mediaviewSaveMsgHiding) {
if (hidingDt >= 0 && _saveMsgOpacity.to() > 0.5) { if (hidingDt >= 0 && _saveMsgOpacity.to() > 0.5) {
_saveMsgOpacity.start(0); _saveMsgOpacity.start(0);
} }
float64 progress = (hidingDt >= 0) ? (hidingDt / st::medviewSaveMsgHiding) : (dt / st::medviewSaveMsgShowing); float64 progress = (hidingDt >= 0) ? (hidingDt / st::mediaviewSaveMsgHiding) : (dt / st::mediaviewSaveMsgShowing);
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear); _saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
if (_saveMsgOpacity.current() > 0) { if (_saveMsgOpacity.current() > 0) {
p.setOpacity(_saveMsgOpacity.current()); p.setOpacity(_saveMsgOpacity.current());
App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners); App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners);
st::medviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::medviewSaveMsgCheckPos, width()); st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
p.setPen(st::mediaviewSaveMsgFg); p.setPen(st::mediaviewSaveMsgFg);
textstyleSet(&st::mediaviewTextStyle); p.setTextPalette(st::mediaviewTextPalette);
_saveMsgText.draw(p, _saveMsg.x() + st::medviewSaveMsgPadding.left(), _saveMsg.y() + st::medviewSaveMsgPadding.top(), _saveMsg.width() - st::medviewSaveMsgPadding.left() - st::medviewSaveMsgPadding.right()); _saveMsgText.draw(p, _saveMsg.x() + st::mediaviewSaveMsgPadding.left(), _saveMsg.y() + st::mediaviewSaveMsgPadding.top(), _saveMsg.width() - st::mediaviewSaveMsgPadding.left() - st::mediaviewSaveMsgPadding.right());
textstyleRestore(); p.restoreTextPalette();
p.setOpacity(1); p.setOpacity(1);
} }
if (_full >= 1) { if (_full >= 1) {
auto nextFrame = (dt < st::medviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::medviewSaveMsgShowing + st::medviewSaveMsgShown + 1 - dt); auto nextFrame = (dt < st::mediaviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::mediaviewSaveMsgShowing + st::mediaviewSaveMsgShown + 1 - dt);
_saveMsgUpdater.start(nextFrame); _saveMsgUpdater.start(nextFrame);
} }
} else { } else {
@ -1630,6 +1726,8 @@ void MediaView::paintEvent(QPaintEvent *e) {
} }
} }
} }
} else if (_themePreviewShown) {
paintThemePreview(p, r);
} else { } else {
if (_docRect.intersects(r)) { if (_docRect.intersects(r)) {
p.fillRect(_docRect, st::mediaviewFileBg); p.fillRect(_docRect, st::mediaviewFileBg);
@ -1642,7 +1740,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
radialOpacity = _radial.opacity(); radialOpacity = _radial.opacity();
} }
if (!_doc || _doc->thumb->isNull()) { if (!_doc || _doc->thumb->isNull()) {
p.fillRect(_docIconRect, (*_docIconColor)->b); p.fillRect(_docIconRect, _docIconColor);
if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) { if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) {
_docIcon->paint(p, _docIconRect.x() + (_docIconRect.width() - _docIcon->width()), _docIconRect.y(), width()); _docIcon->paint(p, _docIconRect.x() + (_docIconRect.width() - _docIcon->width()), _docIconRect.y(), width());
p.setPen(st::mediaviewFileExtFg); p.setPen(st::mediaviewFileExtFg);
@ -1666,7 +1764,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
p.drawTextLeft(_docRect.x() + 2 * st::mediaviewFilePadding + st::mediaviewFileIconSize, _docRect.y() + st::mediaviewFilePadding + st::mediaviewFileNameTop, width(), _docName, _docNameWidth); p.drawTextLeft(_docRect.x() + 2 * st::mediaviewFilePadding + st::mediaviewFileIconSize, _docRect.y() + st::mediaviewFilePadding + st::mediaviewFileNameTop, width(), _docName, _docNameWidth);
p.setPen(st::mediaviewFileSizeFg); p.setPen(st::mediaviewFileSizeFg);
p.setFont(st::mvFont); p.setFont(st::mediaviewFont);
p.drawTextLeft(_docRect.x() + 2 * st::mediaviewFilePadding + st::mediaviewFileIconSize, _docRect.y() + st::mediaviewFilePadding + st::mediaviewFileSizeTop, width(), _docSize, _docSizeWidth); p.drawTextLeft(_docRect.x() + 2 * st::mediaviewFilePadding + st::mediaviewFileIconSize, _docRect.y() + st::mediaviewFilePadding + st::mediaviewFileSizeTop, width(), _docSize, _docSizeWidth);
} }
} }
@ -1685,7 +1783,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
} }
} }
if (_leftNavIcon.intersects(r)) { if (_leftNavIcon.intersects(r)) {
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
st::mediaviewLeft.paintInCenter(p, _leftNavIcon); st::mediaviewLeft.paintInCenter(p, _leftNavIcon);
} }
} }
@ -1701,7 +1799,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
} }
} }
if (_rightNavIcon.intersects(r)) { if (_rightNavIcon.intersects(r)) {
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
st::mediaviewRight.paintInCenter(p, _rightNavIcon); st::mediaviewRight.paintInCenter(p, _rightNavIcon);
} }
} }
@ -1717,7 +1815,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
} }
} }
if (_closeNavIcon.intersects(r)) { if (_closeNavIcon.intersects(r)) {
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
st::mediaviewClose.paintInCenter(p, _closeNavIcon); st::mediaviewClose.paintInCenter(p, _closeNavIcon);
} }
} }
@ -1725,71 +1823,71 @@ void MediaView::paintEvent(QPaintEvent *e) {
// save button // save button
if (_saveVisible && _saveNavIcon.intersects(r)) { if (_saveVisible && _saveNavIcon.intersects(r)) {
auto o = overLevel(OverSave); auto o = overLevel(OverSave);
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
st::mediaviewSave.paintInCenter(p, _saveNavIcon); st::mediaviewSave.paintInCenter(p, _saveNavIcon);
} }
// more area // more area
if (_moreNavIcon.intersects(r)) { if (_moreNavIcon.intersects(r)) {
auto o = overLevel(OverMore); auto o = overLevel(OverMore);
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
st::mediaviewMore.paintInCenter(p, _moreNavIcon); st::mediaviewMore.paintInCenter(p, _moreNavIcon);
} }
p.setPen(st::mediaviewControlFg); p.setPen(st::mediaviewControlFg);
p.setFont(st::mvThickFont); p.setFont(st::mediaviewThickFont);
// header // header
if (_headerNav.intersects(r)) { if (_headerNav.intersects(r)) {
auto o = _headerHasLink ? overLevel(OverHeader) : 0; auto o = _headerHasLink ? overLevel(OverHeader) : 0;
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
p.drawText(_headerNav.left(), _headerNav.top() + st::mvThickFont->ascent, _headerText); p.drawText(_headerNav.left(), _headerNav.top() + st::mediaviewThickFont->ascent, _headerText);
if (o > 0) { if (o > 0) {
p.setOpacity(o * co); p.setOpacity(o * co);
p.drawLine(_headerNav.left(), _headerNav.top() + st::mvThickFont->ascent + 1, _headerNav.right(), _headerNav.top() + st::mvThickFont->ascent + 1); p.drawLine(_headerNav.left(), _headerNav.top() + st::mediaviewThickFont->ascent + 1, _headerNav.right(), _headerNav.top() + st::mediaviewThickFont->ascent + 1);
} }
} }
p.setFont(st::mvFont); p.setFont(st::mediaviewFont);
// name // name
if (_from && _nameNav.intersects(r)) { if (_from && _nameNav.intersects(r)) {
float64 o = overLevel(OverName); float64 o = overLevel(OverName);
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
_fromName.drawElided(p, _nameNav.left(), _nameNav.top(), _nameNav.width()); _fromName.drawElided(p, _nameNav.left(), _nameNav.top(), _nameNav.width());
if (o > 0) { if (o > 0) {
p.setOpacity(o * co); p.setOpacity(o * co);
p.drawLine(_nameNav.left(), _nameNav.top() + st::mvFont->ascent + 1, _nameNav.right(), _nameNav.top() + st::mvFont->ascent + 1); p.drawLine(_nameNav.left(), _nameNav.top() + st::mediaviewFont->ascent + 1, _nameNav.right(), _nameNav.top() + st::mediaviewFont->ascent + 1);
} }
} }
// date // date
if (_dateNav.intersects(r)) { if (_dateNav.intersects(r)) {
float64 o = overLevel(OverDate); float64 o = overLevel(OverDate);
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
p.drawText(_dateNav.left(), _dateNav.top() + st::mvFont->ascent, _dateText); p.drawText(_dateNav.left(), _dateNav.top() + st::mediaviewFont->ascent, _dateText);
if (o > 0) { if (o > 0) {
p.setOpacity(o * co); p.setOpacity(o * co);
p.drawLine(_dateNav.left(), _dateNav.top() + st::mvFont->ascent + 1, _dateNav.right(), _dateNav.top() + st::mvFont->ascent + 1); p.drawLine(_dateNav.left(), _dateNav.top() + st::mediaviewFont->ascent + 1, _dateNav.right(), _dateNav.top() + st::mediaviewFont->ascent + 1);
} }
} }
// caption // caption
if (!_caption.isEmpty()) { if (!_caption.isEmpty()) {
QRect outer(_captionRect.marginsAdded(st::mvCaptionPadding)); QRect outer(_captionRect.marginsAdded(st::mediaviewCaptionPadding));
if (outer.intersects(r)) { if (outer.intersects(r)) {
p.setOpacity(co); p.setOpacity(co);
p.setBrush(st::mediaviewCaptionBg); p.setBrush(st::mediaviewCaptionBg);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.drawRoundedRect(outer, st::mvCaptionRadius, st::mvCaptionRadius); p.drawRoundedRect(outer, st::mediaviewCaptionRadius, st::mediaviewCaptionRadius);
if (_captionRect.intersects(r)) { if (_captionRect.intersects(r)) {
textstyleSet(&st::mediaviewTextStyle); p.setTextPalette(st::mediaviewTextPalette);
p.setPen(st::mediaviewCaptionFg); p.setPen(st::mediaviewCaptionFg);
_caption.drawElided(p, _captionRect.x(), _captionRect.y(), _captionRect.width(), _captionRect.height() / st::mvCaptionFont->height); _caption.drawElided(p, _captionRect.x(), _captionRect.y(), _captionRect.width(), _captionRect.height() / st::mediaviewCaptionStyle.font->height);
textstyleRestore(); p.restoreTextPalette();
} }
} }
} }
@ -1828,6 +1926,49 @@ void MediaView::paintDocRadialLoading(Painter &p, bool radial, float64 radialOpa
} }
} }
void MediaView::paintThemePreview(Painter &p, QRect clip) {
auto fill = _themePreviewRect.intersected(clip);
if (!fill.isEmpty()) {
if (_themePreview) {
p.drawPixmapLeft(_themePreviewRect.x(), _themePreviewRect.y(), width(), _themePreview->preview);
} else {
p.fillRect(fill, st::themePreviewBg);
p.setFont(st::themePreviewLoadingFont);
p.setPen(st::themePreviewLoadingFg);
p.drawText(_themePreviewRect, lang(_themePreviewId ? lng_theme_preview_generating : lng_theme_preview_invalid), QTextOption(style::al_center));
}
}
auto fillOverlay = [this, &p, clip](QRect fill) {
auto clipped = fill.intersected(clip);
if (!clipped.isEmpty()) {
p.setOpacity(st::themePreviewOverlayOpacity);
p.fillRect(clipped, st::themePreviewBg);
p.setOpacity(1.);
}
};
auto titleRect = QRect(_themePreviewRect.x(), _themePreviewRect.y(), _themePreviewRect.width(), st::themePreviewMargin.top());
if (titleRect.x() < 0) {
titleRect = QRect(0, _themePreviewRect.y(), width(), st::themePreviewMargin.top());
}
if (auto fillTitleRect = (titleRect.y() < 0)) {
titleRect.moveTop(0);
fillOverlay(titleRect);
}
titleRect = titleRect.marginsRemoved(QMargins(st::themePreviewMargin.left(), st::themePreviewTitleTop, st::themePreviewMargin.right(), titleRect.height() - st::themePreviewTitleTop - st::themePreviewTitleFont->height));
if (titleRect.intersects(clip)) {
p.setFont(st::themePreviewTitleFont);
p.setPen(st::themePreviewTitleFg);
p.drawTextLeft(titleRect.x(), titleRect.y(), width(), lang(lng_theme_preview_title));
}
auto buttonsRect = QRect(_themePreviewRect.x(), _themePreviewRect.y() + _themePreviewRect.height() - st::themePreviewMargin.bottom(), _themePreviewRect.width(), st::themePreviewMargin.bottom());
if (auto fillButtonsRect = (buttonsRect.y() + buttonsRect.height() > height())) {
buttonsRect.moveTop(height() - buttonsRect.height());
fillOverlay(buttonsRect);
}
}
void MediaView::keyPressEvent(QKeyEvent *e) { void MediaView::keyPressEvent(QKeyEvent *e) {
if (_clipController) { if (_clipController) {
auto toggle1 = (e->key() == Qt::Key_F && e->modifiers().testFlag(Qt::ControlModifier)); auto toggle1 = (e->key() == Qt::Key_F && e->modifiers().testFlag(Qt::ControlModifier));
@ -1856,7 +1997,7 @@ void MediaView::keyPressEvent(QKeyEvent *e) {
} else if (e->key() == Qt::Key_Copy || (e->key() == Qt::Key_C && e->modifiers().testFlag(Qt::ControlModifier))) { } else if (e->key() == Qt::Key_Copy || (e->key() == Qt::Key_C && e->modifiers().testFlag(Qt::ControlModifier))) {
onCopy(); onCopy();
} else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) { } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) {
if (_doc && !_doc->loading() && (!fileShown() || !_doc->loaded())) { if (_doc && !_doc->loading() && (fileBubbleShown() || !_doc->loaded())) {
onDocClick(); onDocClick();
} else if (_doc && _doc->isVideo()) { } else if (_doc && _doc->isVideo()) {
onVideoPauseResume(); onVideoPauseResume();
@ -1957,8 +2098,8 @@ bool MediaView::moveToNext(int32 delta) {
_channel = _history ? _history->channelId() : NoChannel; _channel = _history ? _history->channelId() : NoChannel;
_canForward = _msgid > 0; _canForward = _msgid > 0;
_canDelete = lastChatPhoto.item->canDelete(); _canDelete = lastChatPhoto.item->canDelete();
stopGif(); displayPhoto(lastChatPhoto.photo, lastChatPhoto.item);
displayPhoto(lastChatPhoto.photo, lastChatPhoto.item); preloadData(delta); preloadData(delta);
return true; return true;
} else if (_history && (_history->overviewCount(OverviewChatPhotos) != 0 || ( } else if (_history && (_history->overviewCount(OverviewChatPhotos) != 0 || (
_migrated && _migrated->overviewCount(OverviewChatPhotos) != 0))) { _migrated && _migrated->overviewCount(OverviewChatPhotos) != 0))) {
@ -1994,7 +2135,7 @@ bool MediaView::moveToNext(int32 delta) {
_canForward = _msgid > 0; _canForward = _msgid > 0;
_canDelete = item->canDelete(); _canDelete = item->canDelete();
stopGif(); stopGif();
if (HistoryMedia *media = item->getMedia()) { if (auto media = item->getMedia()) {
switch (media->type()) { switch (media->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break; case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
case MediaTypeFile: case MediaTypeFile:
@ -2013,7 +2154,6 @@ bool MediaView::moveToNext(int32 delta) {
_msgmigrated = false; _msgmigrated = false;
_canForward = false; _canForward = false;
_canDelete = false; _canDelete = false;
stopGif();
displayPhoto(_additionalChatPhoto, 0); displayPhoto(_additionalChatPhoto, 0);
} }
if (delta < 0 && _index < MediaOverviewStartPerPage) { if (delta < 0 && _index < MediaOverviewStartPerPage) {
@ -2189,8 +2329,8 @@ void MediaView::snapXY() {
void MediaView::mouseMoveEvent(QMouseEvent *e) { void MediaView::mouseMoveEvent(QMouseEvent *e) {
updateOver(e->pos()); updateOver(e->pos());
if (_lastAction.x() >= 0 && (e->pos() - _lastAction).manhattanLength() >= st::mvDeltaFromLastAction) { if (_lastAction.x() >= 0 && (e->pos() - _lastAction).manhattanLength() >= st::mediaviewDeltaFromLastAction) {
_lastAction = QPoint(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction); _lastAction = QPoint(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction);
} }
if (_pressed) { if (_pressed) {
if (!_dragging && (e->pos() - _mStart).manhattanLength() >= QApplication::startDragDistance()) { if (!_dragging && (e->pos() - _mStart).manhattanLength() >= QApplication::startDragDistance()) {
@ -2267,7 +2407,7 @@ void MediaView::updateOver(QPoint pos) {
ClickHandlerHost *lnkhost = nullptr; ClickHandlerHost *lnkhost = nullptr;
if (_saveMsgStarted && _saveMsg.contains(pos)) { if (_saveMsgStarted && _saveMsg.contains(pos)) {
auto textState = _saveMsgText.getState(pos.x() - _saveMsg.x() - st::medviewSaveMsgPadding.left(), pos.y() - _saveMsg.y() - st::medviewSaveMsgPadding.top(), _saveMsg.width() - st::medviewSaveMsgPadding.left() - st::medviewSaveMsgPadding.right()); auto textState = _saveMsgText.getState(pos.x() - _saveMsg.x() - st::mediaviewSaveMsgPadding.left(), pos.y() - _saveMsg.y() - st::mediaviewSaveMsgPadding.top(), _saveMsg.width() - st::mediaviewSaveMsgPadding.left() - st::mediaviewSaveMsgPadding.right());
lnk = textState.link; lnk = textState.link;
lnkhost = this; lnkhost = this;
} else if (_captionRect.contains(pos)) { } else if (_captionRect.contains(pos)) {
@ -2302,7 +2442,7 @@ void MediaView::updateOver(QPoint pos) {
updateOverState(OverHeader); updateOverState(OverHeader);
} else if (_saveVisible && _saveNav.contains(pos)) { } else if (_saveVisible && _saveNav.contains(pos)) {
updateOverState(OverSave); updateOverState(OverSave);
} else if (_doc && !fileShown() && _docIconRect.contains(pos)) { } else if (_doc && fileBubbleShown() && _docIconRect.contains(pos)) {
updateOverState(OverIcon); updateOverState(OverIcon);
} else if (_moreNav.contains(pos)) { } else if (_moreNav.contains(pos)) {
updateOverState(OverMore); updateOverState(OverMore);
@ -2358,8 +2498,14 @@ void MediaView::mouseReleaseEvent(QMouseEvent *e) {
} }
_dragging = 0; _dragging = 0;
setCursor(style::cur_default); setCursor(style::cur_default);
} else if ((e->pos() - _lastAction).manhattanLength() >= st::mvDeltaFromLastAction && (!_doc || fileShown() || !_docRect.contains(e->pos()))) { } else if ((e->pos() - _lastAction).manhattanLength() >= st::mediaviewDeltaFromLastAction) {
close(); if (_themePreviewShown) {
if (!_themePreviewRect.contains(e->pos())) {
close();
}
} else if (!_doc || fileShown() || !_docRect.contains(e->pos())) {
close();
}
} }
_pressed = false; _pressed = false;
} }
@ -2422,7 +2568,7 @@ void MediaView::touchEvent(QTouchEvent *e) {
} else if (_touchMove) { } else if (_touchMove) {
if ((!_leftNavVisible || !_leftNav.contains(mapFromGlobal(_touchStart))) && (!_rightNavVisible || !_rightNav.contains(mapFromGlobal(_touchStart)))) { if ((!_leftNavVisible || !_leftNav.contains(mapFromGlobal(_touchStart))) && (!_rightNavVisible || !_rightNav.contains(mapFromGlobal(_touchStart)))) {
QPoint d = (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart); QPoint d = (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart);
if (d.x() * d.x() > d.y() * d.y() && (d.x() > st::mvSwipeDistance || d.x() < -st::mvSwipeDistance)) { if (d.x() * d.x() > d.y() * d.y() && (d.x() > st::mediaviewSwipeDistance || d.x() < -st::mediaviewSwipeDistance)) {
moveToNext(d.x() > 0 ? -1 : 1); moveToNext(d.x() > 0 ? -1 : 1);
} }
} }
@ -2500,6 +2646,7 @@ void MediaView::setVisible(bool visible) {
Sandbox::removeEventFilter(this); Sandbox::removeEventFilter(this);
stopGif(); stopGif();
destroyThemePreview();
_radial.stop(); _radial.stop();
Notify::clipStopperHidden(ClipStopperMediaview); Notify::clipStopperHidden(ClipStopperMediaview);
} }
@ -2746,12 +2893,12 @@ void MediaView::updateHeader() {
} }
} }
_headerHasLink = _history && typeHasMediaOverview(_overview); _headerHasLink = _history && typeHasMediaOverview(_overview);
int32 hwidth = st::mvThickFont->width(_headerText); int32 hwidth = st::mediaviewThickFont->width(_headerText);
if (hwidth > width() / 3) { if (hwidth > width() / 3) {
hwidth = width() / 3; hwidth = width() / 3;
_headerText = st::mvThickFont->elided(_headerText, hwidth, Qt::ElideMiddle); _headerText = st::mediaviewThickFont->elided(_headerText, hwidth, Qt::ElideMiddle);
} }
_headerNav = myrtlrect(st::mvTextLeft, height() - st::mvHeaderTop, hwidth, st::mvThickFont->height); _headerNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewHeaderTop, hwidth, st::mediaviewThickFont->height);
} }
float64 MediaView::overLevel(OverState control) const { float64 MediaView::overLevel(OverState control) const {

View file

@ -32,8 +32,15 @@ class Controller;
namespace Ui { namespace Ui {
class PopupMenu; class PopupMenu;
class LinkButton; class LinkButton;
class RoundButton;
} // namespace Ui } // namespace Ui
namespace Window {
namespace Theme {
struct Preview;
} // namespace Theme
} // namespace Window
struct AudioPlaybackState; struct AudioPlaybackState;
class MediaView : public TWidget, private base::Subscriber, public RPCSender, public ClickHandlerHost { class MediaView : public TWidget, private base::Subscriber, public RPCSender, public ClickHandlerHost {
@ -127,6 +134,20 @@ private slots:
void onVideoPlayProgress(const AudioMsgId &audioId); void onVideoPlayProgress(const AudioMsgId &audioId);
private: private:
enum OverState {
OverNone,
OverLeftNav,
OverRightNav,
OverClose,
OverHeader,
OverName,
OverDate,
OverSave,
OverMore,
OverIcon,
OverVideo,
};
void showSaveMsgFile(); void showSaveMsgFile();
void dropdownHidden(); void dropdownHidden();
@ -155,6 +176,10 @@ private:
void initAnimation(); void initAnimation();
void createClipReader(); void createClipReader();
void initThemePreview();
void destroyThemePreview();
void updateThemePreviewGeometry();
// Radial animation interface. // Radial animation interface.
float64 radialProgress() const; float64 radialProgress() const;
bool radialLoading() const; bool radialLoading() const;
@ -187,6 +212,11 @@ private:
void zoomUpdate(int32 &newZoom); void zoomUpdate(int32 &newZoom);
void paintDocRadialLoading(Painter &p, bool radial, float64 radialOpacity); void paintDocRadialLoading(Painter &p, bool radial, float64 radialOpacity);
void paintThemePreview(Painter &p, QRect clip);
void updateOverRect(OverState state);
bool updateOverState(OverState newState);
float64 overLevel(OverState control) const;
QBrush _transparentBrush; QBrush _transparentBrush;
@ -236,10 +266,11 @@ private:
bool fileShown() const; bool fileShown() const;
bool gifShown() const; bool gifShown() const;
bool fileBubbleShown() const;
void stopGif(); void stopGif();
const style::icon *_docIcon = nullptr; const style::icon *_docIcon = nullptr;
const style::color *_docIconColor = nullptr; style::color _docIconColor;
QString _docName, _docSize, _docExt; QString _docName, _docSize, _docExt;
int _docNameWidth = 0, _docSizeWidth = 0, _docExtWidth = 0; int _docNameWidth = 0, _docSizeWidth = 0, _docExtWidth = 0;
QRect _docRect, _docIconRect; QRect _docRect, _docIconRect;
@ -278,19 +309,6 @@ private:
mtpRequestId _loadRequest = 0; mtpRequestId _loadRequest = 0;
enum OverState {
OverNone,
OverLeftNav,
OverRightNav,
OverClose,
OverHeader,
OverName,
OverDate,
OverSave,
OverMore,
OverIcon,
OverVideo,
};
OverState _over = OverNone; OverState _over = OverNone;
OverState _down = OverNone; OverState _down = OverNone;
QPoint _lastAction, _lastMouseMovePos; QPoint _lastAction, _lastMouseMovePos;
@ -340,8 +358,11 @@ private:
int _verticalWheelDelta = 0; int _verticalWheelDelta = 0;
void updateOverRect(OverState state); bool _themePreviewShown = false;
bool updateOverState(OverState newState); uint64 _themePreviewId = 0;
float64 overLevel(OverState control) const; QRect _themePreviewRect;
std_::unique_ptr<Window::Theme::Preview> _themePreview;
object_ptr<Ui::RoundButton> _themeApply = { nullptr };
object_ptr<Ui::RoundButton> _themeCancel = { nullptr };
}; };

View file

@ -493,7 +493,7 @@ Voice::Voice(DocumentData *voice, HistoryItem *parent, const style::OverviewFile
updateName(); updateName();
QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date)))); QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date))));
TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto }; TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto };
_details.setText(st::normalFont, lng_date_and_duration(lt_date, d, lt_duration, formatDurationText(_data->voice()->duration)), opts); _details.setText(st::defaultTextStyle, lng_date_and_duration(lt_date, d, lt_duration, formatDurationText(_data->voice()->duration)), opts);
_details.setLink(1, goToMessageClickHandler(parent)); _details.setLink(1, goToMessageClickHandler(parent));
} }
@ -578,9 +578,9 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
p.setPen(selected ? st::mediaInFgSelected : st::mediaInFg); p.setPen(selected ? st::mediaInFgSelected : st::mediaInFg);
int32 unreadx = nameleft; int32 unreadx = nameleft;
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) { if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
textstyleSet(&(selected ? st::mediaInStyleSelected : st::mediaInStyle)); p.setTextPalette(selected ? st::mediaInPaletteSelected : st::mediaInPalette);
_details.drawLeftElided(p, nameleft, statustop, namewidth, _width); _details.drawLeftElided(p, nameleft, statustop, namewidth, _width);
textstyleRestore(); p.restoreTextPalette();
unreadx += _details.maxWidth(); unreadx += _details.maxWidth();
} else { } else {
int32 statusw = st::normalFont->width(_status.text()); int32 statusw = st::normalFont->width(_status.text());
@ -631,12 +631,12 @@ void Voice::updateName() {
int32 version = 0; int32 version = 0;
if (const HistoryMessageForwarded *fwd = _parent->Get<HistoryMessageForwarded>()) { if (const HistoryMessageForwarded *fwd = _parent->Get<HistoryMessageForwarded>()) {
if (_parent->fromOriginal()->isChannel()) { if (_parent->fromOriginal()->isChannel()) {
_name.setText(st::semiboldFont, lng_forwarded_channel(lt_channel, App::peerName(_parent->fromOriginal())), _textNameOptions); _name.setText(st::semiboldTextStyle, lng_forwarded_channel(lt_channel, App::peerName(_parent->fromOriginal())), _textNameOptions);
} else { } else {
_name.setText(st::semiboldFont, lng_forwarded(lt_user, App::peerName(_parent->fromOriginal())), _textNameOptions); _name.setText(st::semiboldTextStyle, lng_forwarded(lt_user, App::peerName(_parent->fromOriginal())), _textNameOptions);
} }
} else { } else {
_name.setText(st::semiboldFont, App::peerName(_parent->from()), _textNameOptions); _name.setText(st::semiboldTextStyle, App::peerName(_parent->from()), _textNameOptions);
} }
version = _parent->fromOriginal()->nameVersion; version = _parent->fromOriginal()->nameVersion;
_nameVersion = version; _nameVersion = version;
@ -675,7 +675,7 @@ Document::Document(DocumentData *document, HistoryItem *parent, const style::Ove
, _date(langDateTime(date(_data->date))) , _date(langDateTime(date(_data->date)))
, _datew(st::normalFont->width(_date)) , _datew(st::normalFont->width(_date))
, _colorIndex(documentColorIndex(_data, _ext)) { , _colorIndex(documentColorIndex(_data, _ext)) {
_name.setMarkedText(st::normalFont, documentNameWithEntities(_data), _documentNameOptions); _name.setMarkedText(st::defaultTextStyle, documentNameWithEntities(_data), _documentNameOptions);
AddComponents(Info::Bit()); AddComponents(Info::Bit());
@ -806,7 +806,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
} }
} }
if (selected) { if (selected) {
p.fillRect(rthumb, textstyleCurrent()->selectOverlay); p.fillRect(rthumb, st::defaultTextPalette.selectOverlay);
} }
if (radial || (!loaded && !_data->loading())) { if (radial || (!loaded && !_data->loading())) {
@ -1029,7 +1029,7 @@ Link::Link(HistoryMedia *media, HistoryItem *parent) : ItemBase(parent) {
} }
if (till > from) { if (till > from) {
TextParseOptions opts = { TextParseMultiline, int32(st::linksMaxWidth), 3 * st::normalFont->height, Qt::LayoutDirectionAuto }; TextParseOptions opts = { TextParseMultiline, int32(st::linksMaxWidth), 3 * st::normalFont->height, Qt::LayoutDirectionAuto };
_text.setText(st::normalFont, text.mid(from, till - from), opts); _text.setText(st::defaultTextStyle, text.mid(from, till - from), opts);
} }
int32 tw = 0, th = 0; int32 tw = 0, th = 0;
if (_page && _page->photo) { if (_page && _page->photo) {

View file

@ -87,8 +87,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P
using Update = Window::Theme::BackgroundUpdate; using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) { subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme if (update.paletteChanged()) {
|| update.type == Update::Type::RevertingTheme) {
invalidateCache(); invalidateCache();
} }
}); });

View file

@ -45,7 +45,7 @@ public:
bool psHasNativeNotifications(); bool psHasNativeNotifications();
virtual QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) = 0; virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
static void LibsLoaded(); static void LibsLoaded();
@ -71,7 +71,7 @@ protected:
void psTrayMenuUpdated(); void psTrayMenuUpdated();
void psSetupTrayIcon(); void psSetupTrayIcon();
virtual void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) = 0; virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
private: private:
void updateIconCounters(); void updateIconCounters();

View file

@ -49,7 +49,7 @@ public:
return !(QSysInfo::macVersion() < QSysInfo::MV_10_8); return !(QSysInfo::macVersion() < QSysInfo::MV_10_8);
} }
virtual QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) = 0; virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
void closeWithoutDestroy() override; void closeWithoutDestroy() override;
@ -99,7 +99,7 @@ protected:
void psTrayMenuUpdated(); void psTrayMenuUpdated();
void psSetupTrayIcon(); void psSetupTrayIcon();
virtual void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) = 0; virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
QTimer psUpdatedPositionTimer; QTimer psUpdatedPositionTimer;

View file

@ -205,9 +205,8 @@ MainWindow::MainWindow()
, iconbig256(qsl(":/gui/art/iconbig256.png")) , iconbig256(qsl(":/gui/art/iconbig256.png"))
, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly)) , wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly))
, _private(std_::make_unique<Private>(this)) { , _private(std_::make_unique<Private>(this)) {
QImage tray(qsl(":/gui/art/osxtray.png")); trayImg = st::macTrayIcon.instance(QColor(0, 0, 0, 180), dbisOne);
trayImg = tray.copy(0, cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4)); trayImgSel = st::macTrayIcon.instance(QColor(255, 255, 255), dbisOne);
trayImgSel = tray.copy(tray.width() / (cRetina() ? 2 : 4), cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4));
_hideAfterFullScreenTimer.setSingleShot(true); _hideAfterFullScreenTimer.setSingleShot(true);
connect(&_hideAfterFullScreenTimer, SIGNAL(timeout()), this, SLOT(onHideAfterFullScreen())); connect(&_hideAfterFullScreenTimer, SIGNAL(timeout()), this, SLOT(onHideAfterFullScreen()));
@ -292,39 +291,45 @@ void MainWindow::psUpdateWorkmode() {
} }
} }
void _placeCounter(QImage &img, int size, int count, const style::color &bg, const style::color &color) { void _placeCounter(QImage &img, int size, int count, style::color bg, style::color color) {
if (!count) return; if (!count) return;
auto savedRatio = img.devicePixelRatio();
img.setDevicePixelRatio(1.);
QPainter p(&img); {
QString cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0')); Painter p(&img);
int32 cntSize = cnt.size(); PainterHighQualityEnabler hq(p);
p.setBrush(bg->b); auto cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0'));
p.setPen(Qt::NoPen); auto cntSize = cnt.size();
p.setRenderHint(QPainter::Antialiasing);
int32 fontSize, skip; p.setBrush(bg);
if (size == 22) { p.setPen(Qt::NoPen);
skip = 1; int32 fontSize, skip;
fontSize = 8; if (size == 22) {
} else { skip = 1;
skip = 2; fontSize = 8;
fontSize = 16; } else {
skip = 2;
fontSize = 16;
}
style::font f(fontSize, 0, 0);
int32 w = f->width(cnt), d, r;
if (size == 22) {
d = (cntSize < 2) ? 3 : 2;
r = (cntSize < 2) ? 6 : 5;
} else {
d = (cntSize < 2) ? 6 : 5;
r = (cntSize < 2) ? 9 : 11;
}
p.drawRoundedRect(QRect(size - w - d * 2 - skip, size - f->height - skip, w + d * 2, f->height), r, r);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.setFont(f);
p.setPen(color);
p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt);
} }
style::font f(fontSize, 0, 0); img.setDevicePixelRatio(savedRatio);
int32 w = f->width(cnt), d, r;
if (size == 22) {
d = (cntSize < 2) ? 3 : 2;
r = (cntSize < 2) ? 6 : 5;
} else {
d = (cntSize < 2) ? 6 : 5;
r = (cntSize < 2) ? 9 : 11;
}
p.drawRoundedRect(QRect(size - w - d * 2 - skip, size - f->height - skip, w + d * 2, f->height), r, r);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.setFont(f->f);
p.setPen(color->p);
p.drawText(size - w - d - skip, size - f->height + f->ascent - skip, cnt);
} }
void MainWindow::updateTitleCounter() { void MainWindow::updateTitleCounter() {

View file

@ -47,4 +47,7 @@ private:
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent); object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
int PreviewTitleHeight();
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
} // namespace Platform } // namespace Platform

View file

@ -21,10 +21,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h" #include "stdafx.h"
#include "platform/mac/window_title_mac.h" #include "platform/mac/window_title_mac.h"
#include "mainwindow.h"
#include "ui/widgets/shadow.h" #include "ui/widgets/shadow.h"
#include "styles/style_window.h" #include "styles/style_window.h"
#include "styles/style_mediaview.h"
#include "platform/platform_main_window.h" #include "platform/platform_main_window.h"
#include <Cocoa/Cocoa.h>
#include <CoreFoundation/CFURL.h>
namespace Platform { namespace Platform {
TitleWidget::TitleWidget(MainWindow *parent, int height) : Window::TitleWidget(parent) TitleWidget::TitleWidget(MainWindow *parent, int height) : Window::TitleWidget(parent)
@ -84,4 +89,138 @@ object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return { nullptr }; return { nullptr };
} }
// All the window decorations preview is done without taking cScale() into
// account, with dbisOne scale and without "px" dimensions, because thats
// how it will look in real launched macOS app.
int PreviewTitleHeight() {
if (auto window = qobject_cast<Platform::MainWindow*>(App::wnd())) {
if (auto height = window->getCustomTitleHeight()) {
return height;
}
}
return 22;
}
QImage PreviewWindowSystemButton(QColor inner, QColor border) {
auto buttonSize = 12;
auto fullSize = buttonSize * cIntRetinaFactor();
auto result = QImage(fullSize, fullSize, QImage::Format_ARGB32_Premultiplied);
result.fill(Qt::transparent);
{
Painter p(&result);
PainterHighQualityEnabler hq(p);
p.setPen(border);
p.setBrush(inner);
p.drawEllipse(QRectF(0.5, 0.5, fullSize - 1., fullSize - 1.));
}
result.setDevicePixelRatio(cRetinaFactor());
return std_::move(result);
}
void PreviewWindowTitle(Painter &p, const style::palette &palette, QRect body, int titleHeight, int outerWidth) {
auto titleRect = QRect(body.x(), body.y() - titleHeight, body.width(), titleHeight);
p.fillRect(titleRect, QColor(0, 0, 0));
p.fillRect(titleRect, st::titleBg[palette]);
p.fillRect(titleRect.x(), titleRect.y() + titleRect.height() - st::lineWidth, titleRect.width(), st::lineWidth, st::titleShadow[palette]);
auto useSystemFont = false;
QFont font;
#ifndef OS_MAC_OLD
QStringList families = { qsl(".SF NS Text"), qsl("Helvetica Neue") };
for (auto family : families) {
font.setFamily(family);
if (QFontInfo(font).family() == font.family()) {
useSystemFont = true;
break;
}
}
#endif // OS_MAC_OLD
if (useSystemFont) {
font.setPixelSize((titleHeight * 15) / 24);
} else {
font = st::normalFont;
}
p.setPen(st::titleFgActive[palette]);
p.setFont(font);
p.drawText(titleRect, qsl("Telegram"), style::al_center);
auto isGraphite = ([NSColor currentControlTint] == NSGraphiteControlTint);
auto buttonSkip = 8;
auto graphiteInner = QColor(141, 141, 146);
auto graphiteBorder = QColor(104, 104, 109);
auto closeInner = isGraphite ? graphiteInner : QColor(252, 96, 92);
auto closeBorder = isGraphite ? graphiteBorder : QColor(222, 64, 59);
auto minimizeInner = isGraphite ? graphiteInner : QColor(254, 192, 65);
auto minimizeBorder = isGraphite ? graphiteBorder : QColor(221, 152, 25);
auto maximizeInner = isGraphite ? graphiteInner : QColor(52, 200, 74);
auto maximizeBorder = isGraphite ? graphiteBorder : QColor(21, 164, 41);
auto close = PreviewWindowSystemButton(closeInner, closeBorder);
auto left = buttonSkip;
p.drawImage(titleRect.x() + left, titleRect.y() + (titleRect.height() - (close.height() / cIntRetinaFactor())) / 2, close);
left += (close.width() / cIntRetinaFactor()) + buttonSkip;
auto minimize = PreviewWindowSystemButton(minimizeInner, minimizeBorder);
p.drawImage(titleRect.x() + left, titleRect.y() + (titleRect.height() - (minimize.height() / cIntRetinaFactor())) / 2, minimize);
left += (minimize.width() / cIntRetinaFactor()) + buttonSkip;
auto maximize = PreviewWindowSystemButton(maximizeInner, maximizeBorder);
p.drawImage(titleRect.x() + left, titleRect.y() + (titleRect.height() - (maximize.height() / cIntRetinaFactor())) / 2, maximize);
}
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth) {
auto retina = cIntRetinaFactor();
auto titleHeight = PreviewTitleHeight();
{
Painter p(&preview);
PreviewWindowTitle(p, palette, body, titleHeight, outerWidth);
}
auto inner = QRect(body.x(), body.y() - titleHeight, body.width(), body.height() + titleHeight);
auto retinaRadius = st::macWindowRoundRadius * retina;
auto roundMask = QImage(2 * retinaRadius, 2 * retinaRadius, QImage::Format_ARGB32_Premultiplied);
roundMask.setDevicePixelRatio(cRetinaFactor());
roundMask.fill(Qt::transparent);
{
Painter p(&roundMask);
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(QColor(255, 255, 255));
p.drawRoundedRect(0, 0, 2 * st::macWindowRoundRadius, 2 * st::macWindowRoundRadius, st::macWindowRoundRadius, st::macWindowRoundRadius);
}
QImage corners[4];
corners[0] = roundMask.copy(0, 0, retinaRadius, retinaRadius);
corners[1] = roundMask.copy(retinaRadius, 0, retinaRadius, retinaRadius);
corners[2] = roundMask.copy(0, retinaRadius, retinaRadius, retinaRadius);
corners[3] = roundMask.copy(retinaRadius, retinaRadius, retinaRadius, retinaRadius);
QImage *cornersPointers[] = { &corners[0], &corners[1], &corners[2], &corners[3] };
auto rounded = preview.copy(inner.x() * retina, inner.y() * retina, inner.width() * retina, inner.height() * retina);
Images::prepareRound(rounded, cornersPointers);
preview.fill(st::themePreviewBg->c);
auto topLeft = st::macWindowShadowTopLeft.instance(QColor(0, 0, 0), dbisOne);
auto topRight = topLeft.mirrored(true, false);
auto bottomLeft = topLeft.mirrored(false, true);
auto bottomRight = bottomLeft.mirrored(true, false);
auto extend = QMargins(37, 28, 37, 28);
auto left = topLeft.copy(0, topLeft.height() - retina, extend.left() * retina, retina);
auto top = topLeft.copy(topLeft.width() - retina, 0, retina, extend.top() * retina);
auto right = topRight.copy(topRight.width() - (extend.right() * retina), topRight.height() - retina, extend.right() * retina, retina);
auto bottom = bottomRight.copy(0, bottomRight.height() - (extend.bottom() * retina), retina, extend.bottom() * retina);
{
Painter p(&preview);
p.drawImage(inner.x() - extend.left(), inner.y() - extend.top(), topLeft);
p.drawImage(inner.x() + inner.width() + extend.right() - (topRight.width() / retina), inner.y() - extend.top(), topRight);
p.drawImage(inner.x() - extend.left(), inner.y() + inner.height() + extend.bottom() - (bottomLeft.height() / retina), bottomLeft);
p.drawImage(inner.x() + inner.width() + extend.right() - (bottomRight.width() / retina), inner.y() + inner.height() + extend.bottom() - (bottomRight.height() / retina), bottomRight);
p.drawImage(QRect(inner.x() - extend.left(), inner.y() - extend.top() + (topLeft.height() / retina), extend.left(), extend.top() + inner.height() + extend.bottom() - (topLeft.height() / retina) - (bottomLeft.height() / retina)), left);
p.drawImage(QRect(inner.x() - extend.left() + (topLeft.width() / retina), inner.y() - extend.top(), extend.left() + inner.width() + extend.right() - (topLeft.width() / retina) - (topRight.width() / retina), extend.top()), top);
p.drawImage(QRect(inner.x() + inner.width(), inner.y() - extend.top() + (topRight.height() / retina), extend.right(), extend.top() + inner.height() + extend.bottom() - (topRight.height() / retina) - (bottomRight.height() / retina)), right);
p.drawImage(QRect(inner.x() - extend.left() + (bottomLeft.width() / retina), inner.y() + inner.height(), extend.left() + inner.width() + extend.right() - (bottomLeft.width() / retina) - (bottomRight.width() / retina), extend.bottom()), bottom);
p.drawImage(inner.x(), inner.y(), rounded);
}
}
} // namespace Platform } // namespace Platform

View file

@ -22,6 +22,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "window/window_title.h" #include "window/window_title.h"
namespace Window {
namespace Theme {
int DefaultPreviewTitleHeight();
void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
} // namespace Theme
} // namespace Window
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
#include "platform/mac/window_title_mac.h" #include "platform/mac/window_title_mac.h"
#elif defined Q_OS_WIN // Q_OS_MAC #elif defined Q_OS_WIN // Q_OS_MAC
@ -34,6 +43,14 @@ inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return { nullptr }; return { nullptr };
} }
inline int PreviewTitleHeight() {
return Window::Theme::DefaultPreviewTitleHeight();
}
inline void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth) {
return Window::Theme::DefaultPreviewWindowFramePaint(preview, palette, body, outerWidth);
}
} // namespace Platform } // namespace Platform
#endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX #endif // Q_OS_MAC || Q_OS_WIN || Q_OS_WINRT || Q_OS_LINUX

View file

@ -30,6 +30,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "lang.h" #include "lang.h"
#include "localstorage.h" #include "localstorage.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "window/window_theme.h"
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
@ -143,11 +144,11 @@ public:
bool init(QColor c) { bool init(QColor c) {
_fullsize = st::windowShadow.width(); _fullsize = st::windowShadow.width();
_shift = st::windowShadowShift; _shift = st::windowShadowShift;
QImage cornersImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied); auto cornersImage = QImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied);
{ {
Painter p(&cornersImage); Painter p(&cornersImage);
p.setCompositionMode(QPainter::CompositionMode_Source); p.setCompositionMode(QPainter::CompositionMode_Source);
st::windowShadow.paint(p, 0, 0, _fullsize); st::windowShadow.paint(p, 0, 0, _fullsize, QColor(0, 0, 0));
} }
if (rtl()) cornersImage = cornersImage.mirrored(true, false); if (rtl()) cornersImage = cornersImage.mirrored(true, false);
@ -529,7 +530,6 @@ private:
}; };
_PsShadowWindows _psShadowWindows; _PsShadowWindows _psShadowWindows;
QColor _shActive(0, 0, 0)/*, _shInactive(0, 0, 0)*/;
LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
auto wnd = App::wnd(); auto wnd = App::wnd();
@ -618,6 +618,12 @@ MainWindow::MainWindow()
if (!_taskbarCreatedMsgId) { if (!_taskbarCreatedMsgId) {
_taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); _taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated");
} }
using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.paletteChanged()) {
_psShadowWindows.setColor(st::windowShadowFg->c);
}
});
} }
void MainWindow::TaskbarCreated() { void MainWindow::TaskbarCreated() {
@ -791,7 +797,7 @@ bool MainWindow::psHasNativeNotifications() {
Q_DECLARE_METATYPE(QMargins); Q_DECLARE_METATYPE(QMargins);
void MainWindow::psFirstShow() { void MainWindow::psFirstShow() {
_psShadowWindows.init(_shActive); _psShadowWindows.init(st::windowShadowFg->c);
_shadowsWorking = true; _shadowsWorking = true;
psUpdateMargins(); psUpdateMargins();

View file

@ -52,7 +52,7 @@ public:
bool psHasNativeNotifications(); bool psHasNativeNotifications();
virtual QImage iconWithCounter(int size, int count, const style::color &bg, const style::color &fg, bool smallIcon) = 0; virtual QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) = 0;
static UINT TaskbarCreatedMsgId() { static UINT TaskbarCreatedMsgId() {
return _taskbarCreatedMsgId; return _taskbarCreatedMsgId;
@ -104,13 +104,13 @@ protected:
void psTrayMenuUpdated(); void psTrayMenuUpdated();
void psSetupTrayIcon(); void psSetupTrayIcon();
virtual void placeSmallCounter(QImage &img, int size, int count, const style::color &bg, const QPoint &shift, const style::color &color) = 0; virtual void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) = 0;
QTimer psUpdatedPositionTimer; QTimer psUpdatedPositionTimer;
private: private:
void updateIconCounters(); void updateIconCounters();
void psDestroyIcons(); void psDestroyIcons();
static UINT _taskbarCreatedMsgId; static UINT _taskbarCreatedMsgId;

View file

@ -27,6 +27,15 @@ class IconButton;
class PlainShadow; class PlainShadow;
} // namespace Ui } // namespace Ui
namespace Window {
namespace Theme {
int DefaultPreviewTitleHeight();
void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
} // namespace Theme
} // namespace Window
namespace Platform { namespace Platform {
class TitleWidget : public Window::TitleWidget, private base::Subscriber { class TitleWidget : public Window::TitleWidget, private base::Subscriber {
@ -64,4 +73,12 @@ inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return object_ptr<TitleWidget>(parent); return object_ptr<TitleWidget>(parent);
} }
inline int PreviewTitleHeight() {
return Window::Theme::DefaultPreviewTitleHeight();
}
inline void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth) {
return Window::Theme::DefaultPreviewWindowFramePaint(preview, palette, body, outerWidth);
}
} // namespace Platform } // namespace Platform

View file

@ -19,7 +19,6 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
using "basic.style"; using "basic.style";
using "basic_types.style";
using "ui/widgets/widgets.style"; using "ui/widgets/widgets.style";
using "window/window.style"; using "window/window.style";
@ -38,12 +37,14 @@ profileNameLeft: 26px;
profileNameTop: 9px; profileNameTop: 9px;
profileNameLabel: FlatLabel(defaultFlatLabel) { profileNameLabel: FlatLabel(defaultFlatLabel) {
margin: margins(10px, 5px, 10px, 5px); margin: margins(10px, 5px, 10px, 5px);
font: font(16px semibold);
width: 160px; width: 160px;
maxHeight: 24px; maxHeight: 24px;
textFg: windowBoldFg; textFg: windowBoldFg;
} style: TextStyle(defaultTextStyle) {
profileNameTextStyle: TextStyle(defaultTextStyle) { font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
} }
profileStatusLeft: 27px; profileStatusLeft: 27px;
profileStatusTop: 35px; profileStatusTop: 35px;
@ -135,9 +136,9 @@ profileMemberAdminIcon: icon {{ "profile_admin_star", windowBgActive, point(4px,
profileLimitReachedLabel: FlatLabel(defaultFlatLabel) { profileLimitReachedLabel: FlatLabel(defaultFlatLabel) {
width: 180px; width: 180px;
margin: margins(profileMemberPaddingLeft, 9px, profileMemberPaddingLeft, 6px); margin: margins(profileMemberPaddingLeft, 9px, profileMemberPaddingLeft, 6px);
} style: TextStyle(defaultTextStyle) {
profileLimitReachedStyle: TextStyle(defaultTextStyle) { lineHeight: 19px;
lineHeight: 19px; }
} }
profileReportReasonOther: InputField(defaultInputField) { profileReportReasonOther: InputField(defaultInputField) {

View file

@ -209,7 +209,7 @@ void GroupMembersWidget::refreshLimitReached() {
bool limitReachedShown = (itemsCount() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle(); bool limitReachedShown = (itemsCount() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle();
if (limitReachedShown && !_limitReachedInfo) { if (limitReachedShown && !_limitReachedInfo) {
_limitReachedInfo.create(this, st::profileLimitReachedLabel, st::profileLimitReachedStyle); _limitReachedInfo.create(this, st::profileLimitReachedLabel);
QString title = textRichPrepare(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax())); QString title = textRichPrepare(lng_profile_migrate_reached(lt_count, Global::ChatSizeMax()));
QString body = textRichPrepare(lang(lng_profile_migrate_body)); QString body = textRichPrepare(lang(lng_profile_migrate_body));
QString link = textRichPrepare(lang(lng_profile_migrate_learn_more)); QString link = textRichPrepare(lang(lng_profile_migrate_learn_more));

View file

@ -99,7 +99,7 @@ void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool select
item->peer->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width()); item->peer->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width());
if (item->name.isEmpty()) { if (item->name.isEmpty()) {
item->name.setText(st::semiboldFont, App::peerName(item->peer), _textNameOptions); item->name.setText(st::msgNameStyle, App::peerName(item->peer), _textNameOptions);
} }
int nameLeft = x + st::profileMemberNamePosition.x(); int nameLeft = x + st::profileMemberNamePosition.x();
int nameTop = y + st::profileMemberNamePosition.y(); int nameTop = y + st::profileMemberNamePosition.y();

View file

@ -242,7 +242,7 @@ void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) {
y += st::profileCommonGroupsNameTop; y += st::profileCommonGroupsNameTop;
auto nameWidth = _contentWidth - (x - _contentLeft) - st::profileCommonGroupsPadding.right(); auto nameWidth = _contentWidth - (x - _contentLeft) - st::profileCommonGroupsPadding.right();
if (item->name.isEmpty()) { if (item->name.isEmpty()) {
item->name.setText(st::semiboldFont, App::peerName(item->peer), _textNameOptions); item->name.setText(st::msgNameStyle, App::peerName(item->peer), _textNameOptions);
} }
_items[index]->name.drawLeftElided(p, x, y, nameWidth, width()); _items[index]->name.drawLeftElided(p, x, y, nameWidth, width());
} }

View file

@ -19,7 +19,6 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
using "basic.style"; using "basic.style";
using "basic_types.style";
using "dialogs/dialogs.style"; using "dialogs/dialogs.style";
using "ui/widgets/widgets.style"; using "ui/widgets/widgets.style";
using "boxes/boxes.style"; using "boxes/boxes.style";
@ -50,12 +49,14 @@ settingsNameLeft: 26px;
settingsNameTop: 9px; settingsNameTop: 9px;
settingsNameLabel: FlatLabel(defaultFlatLabel) { settingsNameLabel: FlatLabel(defaultFlatLabel) {
margin: margins(10px, 5px, 10px, 5px); margin: margins(10px, 5px, 10px, 5px);
font: font(16px semibold);
width: 160px; width: 160px;
maxHeight: 24px; maxHeight: 24px;
textFg: windowBoldFg; textFg: windowBoldFg;
} style: TextStyle(defaultTextStyle) {
settingsNameTextStyle: TextStyle(defaultTextStyle) { font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
} }
settingsStatusLeft: 27px; settingsStatusLeft: 27px;
settingsStatusTop: 35px; settingsStatusTop: 35px;
@ -87,7 +88,11 @@ settingsBlockTitleFont: font(15px semibold);
settingsBlockTitleFg: windowBoldFg; settingsBlockTitleFg: windowBoldFg;
settingsBlockTitleTop: 0px; settingsBlockTitleTop: 0px;
settingsPrimaryLabel: FlatLabel(defaultFlatLabel) { settingsPrimaryLabel: FlatLabel(defaultFlatLabel) {
font: boxTextFont; style: TextStyle(defaultTextStyle) {
font: boxTextFont;
linkFont: boxTextFont;
linkFontOver: font(boxFontSize underline);
}
} }
settingsBlockLabel: FlatLabel(settingsPrimaryLabel) { settingsBlockLabel: FlatLabel(settingsPrimaryLabel) {
textFg: windowSubTextFg; textFg: windowSubTextFg;

View file

@ -66,7 +66,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "ui/style/style_core.h" #include "ui/style/style_core.h"
#include "styles/palette.h" #include "styles/palette.h"
#include "styles/style_basic_types.h"
#include "styles/style_basic.h" #include "styles/style_basic.h"
#include "ui/animation.h" #include "ui/animation.h"

View file

@ -27,6 +27,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "apiwrap.h" #include "apiwrap.h"
#include "localstorage.h" #include "localstorage.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h"
#include "ui/toast/toast.h"
#include "styles/style_stickers.h"
namespace Stickers { namespace Stickers {
namespace { namespace {
@ -78,16 +81,19 @@ void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
} }
Local::writeInstalledStickers(); Local::writeInstalledStickers();
Local::writeArchivedStickers(); Local::writeArchivedStickers();
Ui::show(Box<StickersBox>(archived), KeepOtherLayers);
Ui::Toast::Config toast;
toast.text = lang(lng_stickers_packs_archived);
toast.maxWidth = st::stickersToastMaxWidth;
toast.padding = st::stickersToastPadding;
Ui::Toast::Show(App::wnd(), toast);
// Ui::show(Box<StickersBox>(archived), KeepOtherLayers);
emit App::main()->stickersUpdated(); emit App::main()->stickersUpdated();
} }
// For testing: Just apply random subset or your sticker sets as archived. // For testing: Just apply random subset or your sticker sets as archived.
bool applyArchivedResultFake() { bool applyArchivedResultFake() {
if (rand_value<uint32>() % 128 < 64) {
return false;
}
auto sets = QVector<MTPStickerSetCovered>(); auto sets = QVector<MTPStickerSetCovered>();
for (auto &set : Global::RefStickerSets()) { for (auto &set : Global::RefStickerSets()) {
if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) { if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) {

View file

@ -202,3 +202,6 @@ hashtagClose: IconButton {
color: windowBgOver; color: windowBgOver;
} }
} }
stickersToastMaxWidth: 340px;
stickersToastPadding: margins(16px, 13px, 16px, 12px);

View file

@ -60,18 +60,18 @@ ImagePtr generateUserpicImage(const style::icon &icon) {
} // namespace } // namespace
const style::color &peerColor(int index) { style::color peerColor(int index) {
static const style::color *peerColors[kUserColorsCount] = { static style::color peerColors[kUserColorsCount] = {
&st::historyPeer1NameFg, st::historyPeer1NameFg,
&st::historyPeer2NameFg, st::historyPeer2NameFg,
&st::historyPeer3NameFg, st::historyPeer3NameFg,
&st::historyPeer4NameFg, st::historyPeer4NameFg,
&st::historyPeer5NameFg, st::historyPeer5NameFg,
&st::historyPeer6NameFg, st::historyPeer6NameFg,
&st::historyPeer7NameFg, st::historyPeer7NameFg,
&st::historyPeer8NameFg, st::historyPeer8NameFg,
}; };
return *peerColors[index]; return peerColors[index];
} }
ImagePtr userDefPhoto(int index) { ImagePtr userDefPhoto(int index) {
@ -117,7 +117,7 @@ PeerData::PeerData(const PeerId &id) : id(id)
, colorIndex(peerColorIndex(id)) , colorIndex(peerColorIndex(id))
, color(peerColor(colorIndex)) , color(peerColor(colorIndex))
, _userpic(isUser() ? userDefPhoto(colorIndex) : ((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))) { , _userpic(isUser() ? userDefPhoto(colorIndex) : ((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))) {
nameText.setText(st::msgNameFont, QString(), _textNameOptions); nameText.setText(st::msgNameStyle, QString(), _textNameOptions);
} }
void PeerData::updateNameDelayed(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) { void PeerData::updateNameDelayed(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) {
@ -137,7 +137,7 @@ void PeerData::updateNameDelayed(const QString &newName, const QString &newNameO
++nameVersion; ++nameVersion;
name = newName; name = newName;
nameText.setText(st::msgNameFont, name, _textNameOptions); nameText.setText(st::msgNameStyle, name, _textNameOptions);
Notify::PeerUpdate update(this); Notify::PeerUpdate update(this);
update.flags |= UpdateFlag::NameChanged; update.flags |= UpdateFlag::NameChanged;
@ -207,7 +207,7 @@ QPixmap PeerData::genUserpic(int size) const {
const Text &BotCommand::descriptionText() const { const Text &BotCommand::descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) { if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText(st::mentionFont, _description, _textNameOptions); _descriptionText.setText(st::defaultTextStyle, _description, _textNameOptions);
} }
return _descriptionText; return _descriptionText;
} }
@ -387,7 +387,7 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
void UserData::setNameOrPhone(const QString &newNameOrPhone) { void UserData::setNameOrPhone(const QString &newNameOrPhone) {
if (nameOrPhone != newNameOrPhone) { if (nameOrPhone != newNameOrPhone) {
nameOrPhone = newNameOrPhone; nameOrPhone = newNameOrPhone;
phoneText.setText(st::msgNameFont, nameOrPhone, _textNameOptions); phoneText.setText(st::msgNameStyle, nameOrPhone, _textNameOptions);
} }
} }
@ -986,11 +986,9 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, HistoryItem *context,
bool playVideo = data->isVideo() && audioPlayer(); bool playVideo = data->isVideo() && audioPlayer();
bool playAnimation = data->isAnimation(); bool playAnimation = data->isAnimation();
auto &location = data->location(true); auto &location = data->location(true);
if (auto applyTheme = data->name.endsWith(qstr(".tdesktop-theme"))) { if (auto applyTheme = data->isTheme()) {
if (!location.isEmpty() && location.accessEnable()) { if (!location.isEmpty() && location.accessEnable()) {
if (!Window::Theme::Apply(location.name())) { App::wnd()->showDocument(data, context);
// show error?
}
location.accessDisable(); location.accessDisable();
return; return;
} }
@ -1295,11 +1293,9 @@ void DocumentData::performActionOnLoad() {
bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen);
bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen);
bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item && item->getMedia(); bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item && item->getMedia();
if (auto applyTheme = name.endsWith(qstr(".tdesktop-theme"))) { if (auto applyTheme = isTheme()) {
if (!loc.isEmpty() && loc.accessEnable()) { if (!loc.isEmpty() && loc.accessEnable()) {
if (!Window::Theme::Apply(loc.name())) { App::wnd()->showDocument(this, item);
// show error?
}
loc.accessDisable(); loc.accessDisable();
return; return;
} }

View file

@ -203,7 +203,7 @@ static constexpr int kUserColorsCount = 8;
static constexpr int kChatColorsCount = 4; static constexpr int kChatColorsCount = 4;
static constexpr int kChannelColorsCount = 4; static constexpr int kChannelColorsCount = 4;
const style::color &peerColor(int index); style::color peerColor(int index);
ImagePtr userDefPhoto(int index); ImagePtr userDefPhoto(int index);
ImagePtr chatDefPhoto(int index); ImagePtr chatDefPhoto(int index);
ImagePtr channelDefPhoto(int index); ImagePtr channelDefPhoto(int index);
@ -289,7 +289,7 @@ public:
MTPinputPeer input; MTPinputPeer input;
int colorIndex; int colorIndex;
const style::color &color; style::color color;
void setUserpic(ImagePtr userpic); void setUserpic(ImagePtr userpic);
void paintUserpic(Painter &p, int size, int x, int y) const; void paintUserpic(Painter &p, int size, int x, int y) const;
@ -1136,6 +1136,9 @@ public:
bool isGifv() const { bool isGifv() const {
return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive); return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive);
} }
bool isTheme() const {
return name.endsWith(qstr(".tdesktop-theme"), Qt::CaseInsensitive);
}
bool isMusic() const { bool isMusic() const {
if (auto s = song()) { if (auto s = song()) {
return (s->duration > 0); return (s->duration > 0);

View file

@ -337,15 +337,15 @@ FORCE_INLINE QColor color(QColor a, QColor b, float64 b_ratio) {
#endif // SHIFTED_USE_32BIT #endif // SHIFTED_USE_32BIT
FORCE_INLINE QColor color(const style::color &a, QColor b, float64 b_ratio) { FORCE_INLINE QColor color(style::color a, QColor b, float64 b_ratio) {
return color(a->c, b, b_ratio); return color(a->c, b, b_ratio);
} }
FORCE_INLINE QColor color(QColor a, const style::color &b, float64 b_ratio) { FORCE_INLINE QColor color(QColor a, style::color b, float64 b_ratio) {
return color(a, b->c, b_ratio); return color(a, b->c, b_ratio);
} }
FORCE_INLINE QColor color(const style::color &a, const style::color &b, float64 b_ratio) { FORCE_INLINE QColor color(style::color a, style::color b, float64 b_ratio) {
return color(a->c, b->c, b_ratio); return color(a->c, b->c, b_ratio);
} }
@ -353,15 +353,15 @@ FORCE_INLINE QPen pen(QColor a, QColor b, float64 b_ratio) {
return color(a, b, b_ratio); return color(a, b, b_ratio);
} }
FORCE_INLINE QPen pen(const style::color &a, QColor b, float64 b_ratio) { FORCE_INLINE QPen pen(style::color a, QColor b, float64 b_ratio) {
return (b_ratio > 0) ? pen(a->c, b, b_ratio) : a; return (b_ratio > 0) ? pen(a->c, b, b_ratio) : a;
} }
FORCE_INLINE QPen pen(QColor a, const style::color &b, float64 b_ratio) { FORCE_INLINE QPen pen(QColor a, style::color b, float64 b_ratio) {
return (b_ratio < 1) ? pen(a, b->c, b_ratio) : b; return (b_ratio < 1) ? pen(a, b->c, b_ratio) : b;
} }
FORCE_INLINE QPen pen(const style::color &a, const style::color &b, float64 b_ratio) { FORCE_INLINE QPen pen(style::color a, style::color b, float64 b_ratio) {
return (b_ratio > 0) ? ((b_ratio < 1) ? pen(a->c, b->c, b_ratio) : b) : a; return (b_ratio > 0) ? ((b_ratio < 1) ? pen(a->c, b->c, b_ratio) : b) : a;
} }
@ -369,15 +369,15 @@ FORCE_INLINE QBrush brush(QColor a, QColor b, float64 b_ratio) {
return color(a, b, b_ratio); return color(a, b, b_ratio);
} }
FORCE_INLINE QBrush brush(const style::color &a, QColor b, float64 b_ratio) { FORCE_INLINE QBrush brush(style::color a, QColor b, float64 b_ratio) {
return (b_ratio > 0) ? brush(a->c, b, b_ratio) : a; return (b_ratio > 0) ? brush(a->c, b, b_ratio) : a;
} }
FORCE_INLINE QBrush brush(QColor a, const style::color &b, float64 b_ratio) { FORCE_INLINE QBrush brush(QColor a, style::color b, float64 b_ratio) {
return (b_ratio < 1) ? brush(a, b->c, b_ratio) : b; return (b_ratio < 1) ? brush(a, b->c, b_ratio) : b;
} }
FORCE_INLINE QBrush brush(const style::color &a, const style::color &b, float64 b_ratio) { FORCE_INLINE QBrush brush(style::color a, style::color b, float64 b_ratio) {
return (b_ratio > 0) ? ((b_ratio < 1) ? brush(a->c, b->c, b_ratio) : b) : a; return (b_ratio > 0) ? ((b_ratio < 1) ? brush(a->c, b->c, b_ratio) : b) : a;
} }

View file

@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Ui { namespace Ui {
void CrossAnimation::paint(Painter &p, const style::CrossAnimation &st, const style::color &color, int x, int y, int outerWidth, float64 shown) { void CrossAnimation::paint(Painter &p, const style::CrossAnimation &st, style::color color, int x, int y, int outerWidth, float64 shown) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
auto deleteScale = shown + st.minScale * (1. - shown); auto deleteScale = shown + st.minScale * (1. - shown);

View file

@ -26,7 +26,7 @@ namespace Ui {
class CrossAnimation { class CrossAnimation {
public: public:
static void paint(Painter &p, const style::CrossAnimation &st, const style::color &color, int x, int y, int outerWidth, float64 shown); static void paint(Painter &p, const style::CrossAnimation &st, style::color color, int x, int y, int outerWidth, float64 shown);
}; };

View file

@ -70,7 +70,7 @@ void RadialAnimation::step(TimeMs ms) {
_animation.step(ms); _animation.step(ms);
} }
void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color) { void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, style::color color) {
float64 o = p.opacity(); float64 o = p.opacity();
p.setOpacity(o * _opacity); p.setOpacity(o * _opacity);

View file

@ -42,7 +42,7 @@ public:
step(getms()); step(getms());
} }
void draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color); void draw(Painter &p, const QRect &inner, int32 thickness, style::color color);
private: private:
TimeMs _firstStart = 0; TimeMs _firstStart = 0;

View file

@ -51,13 +51,13 @@ public:
} }
private: private:
void paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) override; void paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) override;
}; };
const TypingAnimation::MetaData TypingAnimation::kMeta = { 0, &TypingAnimation::create }; const TypingAnimation::MetaData TypingAnimation::kMeta = { 0, &TypingAnimation::create };
void TypingAnimation::paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) { void TypingAnimation::paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(color); p.setBrush(color);
@ -96,13 +96,13 @@ public:
} }
private: private:
void paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) override; void paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) override;
}; };
const RecordAnimation::MetaData RecordAnimation::kMeta = { 0, &RecordAnimation::create }; const RecordAnimation::MetaData RecordAnimation::kMeta = { 0, &RecordAnimation::create };
void RecordAnimation::paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) { void RecordAnimation::paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
auto pen = color->p; auto pen = color->p;
pen.setWidth(st::historySendActionRecordStrokeNumerator / st::historySendActionRecordDenominator); pen.setWidth(st::historySendActionRecordStrokeNumerator / st::historySendActionRecordDenominator);
@ -140,13 +140,13 @@ public:
} }
private: private:
void paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) override; void paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) override;
}; };
const UploadAnimation::MetaData UploadAnimation::kMeta = { 0, &UploadAnimation::create }; const UploadAnimation::MetaData UploadAnimation::kMeta = { 0, &UploadAnimation::create };
void UploadAnimation::paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) { void UploadAnimation::paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
auto pen = color->p; auto pen = color->p;
pen.setWidth(st::historySendActionUploadStrokeNumerator / st::historySendActionUploadDenominator); pen.setWidth(st::historySendActionUploadStrokeNumerator / st::historySendActionUploadDenominator);

View file

@ -32,7 +32,7 @@ public:
int width() const { int width() const {
return _impl ? _impl->width() : 0; return _impl ? _impl->width() : 0;
} }
void paint(Painter &p, const style::color &color, int x, int y, int outerWidth, TimeMs ms) { void paint(Painter &p, style::color color, int x, int y, int outerWidth, TimeMs ms) {
if (_impl) { if (_impl) {
_impl->paint(p, color, x, y, outerWidth, ms); _impl->paint(p, color, x, y, outerWidth, ms);
} }
@ -57,14 +57,14 @@ public:
bool supports(Type type) const; bool supports(Type type) const;
virtual int width() const = 0; virtual int width() const = 0;
void paint(Painter &p, const style::color &color, int x, int y, int outerWidth, TimeMs ms) { void paint(Painter &p, style::color color, int x, int y, int outerWidth, TimeMs ms) {
paintFrame(p, color, x, y, outerWidth, qMax(ms - _started, 0LL) % _period); paintFrame(p, color, x, y, outerWidth, qMax(ms - _started, 0LL) % _period);
} }
virtual ~Impl() = default; virtual ~Impl() = default;
private: private:
virtual void paintFrame(Painter &p, const style::color &color, int x, int y, int outerWidth, int frameMs) = 0; virtual void paintFrame(Painter &p, style::color color, int x, int y, int outerWidth, int frameMs) = 0;
int _period = 1; int _period = 1;
TimeMs _started = 0; TimeMs _started = 0;

Some files were not shown because too many files have changed in this diff Show more