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 "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";
@ -36,18 +48,22 @@ emojiPadding: 1px;
lineWidth: 1px;
defaultTooltip: Tooltip {
textBg: tooltipBg;
textFg: tooltipFg;
textFont: normalFont;
textBorder: tooltipBorderFg;
textPadding: margins(5px, 2px, 5px, 2px);
shift: point(-20px, 20px);
skip: 10px;
widthMax: 800px;
linesMax: 12;
defaultTextPalette: TextPalette {
linkFg: windowActiveTextFg;
monoFg: windowSubTextFg;
selectBg: msgInBgSelected;
selectOverlay: msgSelectOverlay;
}
defaultTextStyle: TextStyle {
font: normalFont;
linkFont: normalFont;
linkFontOver: font(fsize underline);
lineHeight: 0px;
}
semiboldTextStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: font(fsize semibold underline);
}
shadowToggleDuration: 200;
@ -75,6 +91,7 @@ activeFadeOutDuration: 3000;
msgMaxWidth: 430px;
msgFont: font(fsize);
msgNameFont: semiboldFont;
msgNameStyle: semiboldTextStyle;
msgServiceFont: semiboldFont;
msgServiceNameFont: semiboldFont;
msgServicePhotoWidth: 100px;
@ -102,56 +119,43 @@ msgDateImgDelta: 4px;
msgDateImgPadding: point(8px, 2px);
msgDateImgCheckSpace: 4px;
defaultTextStyle: TextStyle {
linkFlags: font(fsize);
linkFlagsOver: font(fsize underline);
linkFg: windowActiveTextFg;
linkFgDown: windowActiveTextFg;
monoFg: windowSubTextFg;
selectBg: msgInBgSelected;
selectOverlay: msgSelectOverlay;
lineHeight: 0px;
}
serviceTextStyle: TextStyle(defaultTextStyle) {
linkFlags: msgServiceFont;
linkFlagsOver: font(fsize semibold underline);
messageTextStyle: defaultTextStyle;
msgDateTextStyle: defaultTextStyle;
serviceTextPalette: TextPalette(defaultTextPalette) {
linkFg: msgServiceFg;
linkFgDown: msgServiceFg;
monoFg: msgServiceFg;
selectBg: msgServiceBgSelected;
selectOverlay: msgServiceBgSelected;
}
inTextStyle: TextStyle(defaultTextStyle) {
serviceTextStyle: TextStyle(defaultTextStyle) {
font: msgServiceFont;
linkFont: msgServiceFont;
linkFontOver: font(fsize semibold underline);
}
inTextPalette: TextPalette(defaultTextPalette) {
monoFg: msgInMonoFg;
selectBg: msgInBgSelected;
selectOverlay: msgSelectOverlay;
}
outTextStyle: TextStyle(defaultTextStyle) {
outTextPalette: TextPalette(defaultTextPalette) {
monoFg: msgOutMonoFg;
selectBg: msgOutBgSelected;
selectOverlay: msgSelectOverlay;
}
inFwdTextStyle: TextStyle(defaultTextStyle) {
linkFlags: semiboldFont;
linkFlagsOver: semiboldFont;
fwdTextStyle: TextStyle(semiboldTextStyle) {
linkFontOver: semiboldFont;
}
inFwdTextPalette: TextPalette(defaultTextPalette) {
linkFg: msgInServiceFg;
linkFgDown: msgInServiceFg;
}
outFwdTextStyle: TextStyle(inFwdTextStyle) {
outFwdTextPalette: TextPalette(defaultTextPalette) {
linkFg: msgOutServiceFg;
linkFgDown: msgOutServiceFg;
}
inFwdTextStyleSelected: TextStyle(inFwdTextStyle) {
inFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
linkFg: msgInServiceFgSelected;
linkFgDown: msgInServiceFgSelected;
}
outFwdTextStyleSelected: TextStyle(inFwdTextStyle) {
outFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
linkFg: msgOutServiceFgSelected;
linkFgDown: msgOutServiceFgSelected;
}
mediaviewTextStyle: TextStyle(defaultTextStyle) {
linkFg: mediaviewTextLinkFg;
linkFgDown: mediaviewTextLinkFg;
}
mediaPadding: margins(0px, 0px, 0px, 0px);
@ -164,37 +168,13 @@ mediaUnreadSize: 7px;
mediaUnreadSkip: 5px;
mediaUnreadTop: 6px;
mediaInStyle: TextStyle(defaultTextStyle) {
mediaInPalette: TextPalette(defaultTextPalette) {
linkFg: mediaInFg;
linkFgDown: mediaInFg;
}
mediaInStyleSelected: TextStyle(defaultTextStyle) {
mediaInPaletteSelected: TextPalette(defaultTextPalette) {
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);
searchedBarHeight: 32px;
@ -229,44 +209,6 @@ maxStickerSize: 256px;
maxGifSize: 320px;
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);
radialLine: 3px;
radialDuration: 350;
@ -285,11 +227,13 @@ locationSize: size(320px, 240px);
webPageLeft: 10px;
webPageBar: 2px;
webPageTitleFont: semiboldFont;
webPageTitleStyle: semiboldTextStyle;
webPageTitleOutFg: historyTextOutFg;
webPageTitleInFg: historyTextInFg;
webPageDescriptionOutFg: historyTextOutFg;
webPageDescriptionInFg: historyTextInFg;
webPageDescriptionFont: normalFont;
webPageDescriptionStyle: defaultTextStyle;
webPagePhotoSize: 100px;
webPagePhotoDelta: 8px;
@ -315,7 +259,7 @@ inlineRowFileDescriptionTop: 23px;
inlineResultsMinWidth: 64px;
inlineDurationMargin: 3px;
toastFont: normalFont;
toastTextStyle: defaultTextStyle;
toastMaxWidth: 480px;
toastMinMargin: 13px;
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_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_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;
windowBgOver: #f1f1f1;
windowBgRipple: #e5e5e5;
windowFgOver: windowFg;
windowFgOver: #000000; // windowBgOver;
windowSubTextFg: #999999;
windowSubTextFgOver: #919191;
windowBoldFg: #222222;
@ -37,34 +37,34 @@ windowShadowFg: #000000;
windowShadowFgFallback: #f1f1f1;
shadowFg: #00000018;
slideFadeOutBg: #0000003c;
slideFadeOutShadowFg: windowShadowFg;
slideFadeOutShadowFg: #000000; // windowShadowFgFallback;
imageBg: #000000;
imageBgTransparent: #ffffff;
activeButtonBg: windowBgActive;
activeButtonBg: #40a7e3; // windowFgActive;
activeButtonBgOver: #39a5db;
activeButtonBgRipple: #2095d0;
activeButtonFg: windowFgActive;
activeButtonFgOver: activeButtonFg;
activeButtonFg: #ffffff; // windowActiveTextFg;
activeButtonFgOver: activeButtonFgOver;
activeButtonSecondaryFg: #cceeff;
activeButtonSecondaryFgOver: activeButtonSecondaryFg;
activeButtonSecondaryFgOver: activeButtonSecondaryFgOver;
activeLineFg: #37a1de;
activeLineFgError: #e48383;
lightButtonBg: windowBg;
lightButtonBg: #ffffff; // windowFg;
lightButtonBgOver: #e3f1fa;
lightButtonBgRipple: #c9e4f6;
lightButtonFg: windowActiveTextFg;
lightButtonFgOver: lightButtonFg;
lightButtonFg: #168acd; // windowShadowFg;
lightButtonFgOver: lightButtonFgOver;
attentionButtonFg: #d14e4e;
attentionButtonFgOver: #d14e4e;
attentionButtonBgOver: #fcdfde;
attentionButtonBgRipple: #f4c3c2;
outlineButtonBg: windowBg;
outlineButtonBgOver: lightButtonBgOver;
outlineButtonOutlineFg: windowBgActive;
outlineButtonBgRipple: lightButtonBgRipple;
menuBg: windowBg;
menuBgOver: windowBgOver;
menuBgRipple: windowBgRipple;
outlineButtonBg: #ffffff; // windowFg;
outlineButtonBgOver: #e3f1fa; // lightButtonBgRipple;
outlineButtonOutlineFg: #40a7e3; // windowFgActive;
outlineButtonBgRipple: #c9e4f6; // lightButtonFg;
menuBg: #ffffff; // windowFg;
menuBgOver: #f1f1f1; // windowBgRipple;
menuBgRipple: #e5e5e5; // windowFgOver;
menuIconFg: #a8a8a8;
menuIconFgOver: #999999;
menuSubmenuArrowFg: #373737;
@ -76,25 +76,25 @@ scrollBg: #0000001a;
scrollBgOver: #0000002c;
smallCloseIconFg: #c7c7c7;
smallCloseIconFgOver: #a3a3a3;
radialFg: windowFgActive;
radialFg: #ffffff; // windowActiveTextFg;
radialBg: #00000056;
placeholderFg: windowSubTextFg;
placeholderFg: #999999; // windowSubTextFgOver;
placeholderFgActive: #aaaaaa;
inputBorderFg: #e0e0e0;
filterInputBorderFg: #54c3f3;
checkboxFg: #b3b3b3;
sliderBgInactive: #e1eaef;
sliderBgActive: windowBgActive;
sliderBgActive: #40a7e3; // windowFgActive;
tooltipBg: #eef2f5;
tooltipFg: #5d6c80;
tooltipBorderFg: #c9d1db;
titleBg: windowBgOver;
titleBg: #f1f1f1; // windowBgRipple;
titleShadow: #00000003;
titleButtonFg: #ababab;
titleButtonBgOver: #e5e5e5;
titleButtonFgOver: #9a9a9a;
titleButtonCloseBgOver: #e81123;
titleButtonCloseFgOver: windowFgActive;
titleButtonCloseFgOver: #ffffff; // windowActiveTextFg;
titleFgActive: #3e3c3e;
titleFg: #acacac;
trayCounterBg: #f23c34;
@ -103,32 +103,32 @@ trayCounterFg: #ffffff;
trayCounterBgMacInvert: #ffffff;
trayCounterFgMacInvert: #ffffff01;
layerBg: #0000007f;
cancelIconFg: menuIconFg;
cancelIconFgOver: menuIconFgOver;
boxBg: windowBg;
boxTextFg: windowFg;
cancelIconFg: #a8a8a8; // menuIconFgOver;
cancelIconFgOver: #999999; // menuSubmenuArrowFg;
boxBg: #ffffff; // windowFg;
boxTextFg: #000000; // windowBgOver;
boxTextFgGood: #4ab44a;
boxTextFgError: #d84d4d;
boxTitleFg: #404040;
boxSearchBg: boxBg;
boxSearchCancelIconFg: cancelIconFg;
boxSearchCancelIconFgOver: cancelIconFgOver;
boxSearchBg: #ffffff; // boxTextFg;
boxSearchCancelIconFg: #a8a8a8; // cancelIconFgOver;
boxSearchCancelIconFgOver: #999999; // boxBg;
boxTitleAdditionalFg: #808080;
boxTitleCloseFg: cancelIconFg;
boxTitleCloseFgOver: cancelIconFgOver;
membersAboutLimitFg: windowSubTextFgOver;
contactsBg: windowBg;
contactsBgOver: windowBgOver;
contactsNameFg: boxTextFg;
contactsStatusFg: windowSubTextFg;
contactsStatusFgOver: windowSubTextFgOver;
contactsStatusFgOnline: windowActiveTextFg;
photoCropFadeBg: layerBg;
boxTitleCloseFg: #a8a8a8; // cancelIconFgOver;
boxTitleCloseFgOver: #999999; // boxBg;
membersAboutLimitFg: #919191; // windowBoldFg;
contactsBg: #ffffff; // windowFg;
contactsBgOver: #f1f1f1; // windowBgRipple;
contactsNameFg: #000000; // boxTextFgGood;
contactsStatusFg: #999999; // windowSubTextFgOver;
contactsStatusFgOver: #919191; // windowBoldFg;
contactsStatusFgOnline: #168acd; // windowShadowFg;
photoCropFadeBg: #0000007f; // cancelIconFg;
photoCropPointFg: #ffffff7f;
introBg: windowBg;
introTitleFg: windowBoldFg;
introDescriptionFg: windowSubTextFg;
introErrorFg: windowSubTextFg;
introBg: #ffffff; // windowFg;
introTitleFg: windowBoldFgOver;
introDescriptionFg: #999999; // windowSubTextFgOver;
introErrorFg: #999999; // windowSubTextFgOver;
introCoverTopBg: #0f89d0;
introCoverBottomBg: #39b0f0;
introCoverIconsFg: #5ec6ff;
@ -136,83 +136,83 @@ introCoverPlaneTrace: #5ec6ff69;
introCoverPlaneInner: #c6d8e8;
introCoverPlaneOuter: #a1bed4;
introCoverPlaneTop: #ffffff;
dialogsMenuIconFg: menuIconFg;
dialogsMenuIconFgOver: menuIconFgOver;
dialogsBg: windowBg;
dialogsNameFg: windowBoldFg;
dialogsChatIconFg: dialogsNameFg;
dialogsDateFg: windowSubTextFg;
dialogsTextFg: windowSubTextFg;
dialogsTextFgService: windowActiveTextFg;
dialogsMenuIconFg: #a8a8a8; // menuIconFgOver;
dialogsMenuIconFgOver: #999999; // menuSubmenuArrowFg;
dialogsBg: #ffffff; // windowFg;
dialogsNameFg: windowBoldFgOver;
dialogsChatIconFg: dialogsChatIconFg;
dialogsDateFg: #999999; // windowSubTextFgOver;
dialogsTextFg: #999999; // windowSubTextFgOver;
dialogsTextFgService: #168acd; // windowShadowFg;
dialogsDraftFg: #dd4b39;
dialogsVerifiedIconBg: windowBgActive;
dialogsVerifiedIconFg: windowFgActive;
dialogsVerifiedIconBg: #40a7e3; // windowFgActive;
dialogsVerifiedIconFg: #ffffff; // windowActiveTextFg;
dialogsSendingIconFg: #c1c1c1;
dialogsSentIconFg: #5dc452;
dialogsUnreadBg: windowBgActive;
dialogsUnreadBg: #40a7e3; // windowFgActive;
dialogsUnreadBgMuted: #bbbbbb;
dialogsUnreadFg: windowFgActive;
dialogsBgOver: windowBgOver;
dialogsNameFgOver: windowBoldFgOver;
dialogsChatIconFgOver: dialogsNameFgOver;
dialogsDateFgOver: windowSubTextFgOver;
dialogsTextFgOver: windowSubTextFgOver;
dialogsTextFgServiceOver: dialogsTextFgService;
dialogsDraftFgOver: dialogsDraftFg;
dialogsVerifiedIconBgOver: dialogsVerifiedIconBg;
dialogsVerifiedIconFgOver: dialogsVerifiedIconFg;
dialogsSendingIconFgOver: dialogsSendingIconFg;
dialogsSentIconFgOver: dialogsSentIconFg;
dialogsUnreadBgOver: dialogsUnreadBg;
dialogsUnreadBgMutedOver: dialogsUnreadBgMuted;
dialogsUnreadFgOver: dialogsUnreadFg;
dialogsUnreadFg: #ffffff; // windowActiveTextFg;
dialogsBgOver: #f1f1f1; // windowBgRipple;
dialogsNameFgOver: #222222; // windowBgActive;
dialogsChatIconFgOver: dialogsChatIconFgOver;
dialogsDateFgOver: #919191; // windowBoldFg;
dialogsTextFgOver: #919191; // windowBoldFg;
dialogsTextFgServiceOver: #168acd; // dialogsDraftFg;
dialogsDraftFgOver: #dd4b39; // dialogsVerifiedIconBg;
dialogsVerifiedIconBgOver: #40a7e3; // dialogsVerifiedIconFg;
dialogsVerifiedIconFgOver: #ffffff; // dialogsSendingIconFg;
dialogsSendingIconFgOver: #c1c1c1; // dialogsSentIconFg;
dialogsSentIconFgOver: #5dc452; // dialogsUnreadBg;
dialogsUnreadBgOver: #40a7e3; // dialogsUnreadBgMuted;
dialogsUnreadBgMutedOver: #bbbbbb; // dialogsUnreadFg;
dialogsUnreadFgOver: #ffffff; // dialogsBgOver;
dialogsBgActive: #419fd9;
dialogsNameFgActive: windowFgActive;
dialogsChatIconFgActive: dialogsNameFgActive;
dialogsDateFgActive: windowFgActive;
dialogsTextFgActive: windowFgActive;
dialogsTextFgServiceActive: dialogsTextFgActive;
dialogsNameFgActive: #ffffff; // windowActiveTextFg;
dialogsChatIconFgActive: dialogsChatIconFgActive;
dialogsDateFgActive: #ffffff; // windowActiveTextFg;
dialogsTextFgActive: #ffffff; // windowActiveTextFg;
dialogsTextFgServiceActive: dialogsTextFgServiceActive;
dialogsDraftFgActive: #c6e1f7;
dialogsVerifiedIconBgActive: dialogsTextFgActive;
dialogsVerifiedIconFgActive: dialogsBgActive;
dialogsVerifiedIconBgActive: dialogsTextFgServiceActive;
dialogsVerifiedIconFgActive: #419fd9; // dialogsNameFgActive;
dialogsSendingIconFgActive: #ffffff99;
dialogsSentIconFgActive: dialogsTextFgActive;
dialogsUnreadBgActive: dialogsTextFgActive;
dialogsUnreadBgMutedActive: dialogsDraftFgActive;
dialogsUnreadFgActive: dialogsBgActive;
dialogsForwardBg: dialogsBgActive;
dialogsForwardFg: dialogsNameFgActive;
searchedBarBg: windowBgOver;
searchedBarBorder: shadowFg;
searchedBarFg: windowSubTextFgOver;
topBarBg: windowBg;
emojiPanBg: windowBg;
emojiPanCategories: #f7f7f7; // windowBg;
emojiPanHeaderFg: windowSubTextFg;
emojiPanHeaderBg: #fffffff2; // emojiPanBg;
dialogsSentIconFgActive: dialogsTextFgServiceActive;
dialogsUnreadBgActive: dialogsTextFgServiceActive;
dialogsUnreadBgMutedActive: #c6e1f7; // dialogsVerifiedIconBgActive;
dialogsUnreadFgActive: #419fd9; // dialogsNameFgActive;
dialogsForwardBg: #419fd9; // dialogsNameFgActive;
dialogsForwardFg: dialogsChatIconFgActive;
searchedBarBg: #f1f1f1; // windowBgRipple;
searchedBarBorder: #00000018; // slideFadeOutBg;
searchedBarFg: #919191; // windowBoldFg;
topBarBg: #ffffff; // windowFg;
emojiPanBg: #ffffff; // windowFg;
emojiPanCategories: #f7f7f7; // windowFg;
emojiPanHeaderFg: #999999; // windowSubTextFgOver;
emojiPanHeaderBg: #fffffff2; // emojiPanCategories;
stickerPanDeleteBg: #000000cc;
stickerPanDeleteFg: windowFgActive;
stickerPanDeleteFg: #ffffff; // windowActiveTextFg;
stickerPreviewBg: #ffffffb0;
historyTextInFg: windowFg;
historyTextOutFg: windowFg;
historyCaptionInFg: historyTextInFg;
historyCaptionOutFg: historyTextOutFg;
historyFileNameInFg: historyTextInFg;
historyFileNameOutFg: historyTextOutFg;
historyOutIconFg: dialogsSentIconFg;
historyTextInFg: #000000; // windowBgOver;
historyTextOutFg: #000000; // windowBgOver;
historyCaptionInFg: historyTextOutFg;
historyCaptionOutFg: historyCaptionInFg;
historyFileNameInFg: historyTextOutFg;
historyFileNameOutFg: historyCaptionInFg;
historyOutIconFg: #5dc452; // dialogsUnreadBg;
historyOutIconFgSelected: #4da79f;
historyIconFgInverted: windowFgActive;
historyIconFgInverted: #ffffff; // windowActiveTextFg;
historySendingOutIconFg: #98d292;
historySendingInIconFg: #a0adb5;
historySendingInvertedIconFg: #ffffffc8;
historySystemBg: #89a0b47f;
historySystemBgSelected: #bbc8d4a2;
historySystemFg: windowFgActive;
historySystemFg: #ffffff; // windowActiveTextFg;
historyUnreadBarBg: #fcfbfa;
historyUnreadBarBorder: shadowFg;
historyUnreadBarBorder: #00000018; // slideFadeOutBg;
historyUnreadBarFg: #538bb4;
historyForwardChooseBg: #0000004c;
historyForwardChooseFg: windowFgActive;
historyForwardChooseFg: #ffffff; // windowActiveTextFg;
historyPeer1NameFg: #c03d33;
historyPeer1UserpicBg: #ed9482;
historyPeer1UserpicFg: #d3644b;
@ -222,7 +222,7 @@ historyPeer2UserpicFg: #75c057;
historyPeer3NameFg: #d09306;
historyPeer3UserpicBg: #efd289;
historyPeer3UserpicFg: #e4a861;
historyPeer4NameFg: windowActiveTextFg;
historyPeer4NameFg: #168acd; // windowShadowFg;
historyPeer4UserpicBg: #8fbfe9;
historyPeer4UserpicFg: #649fd3;
historyPeer5NameFg: #8544d6;
@ -241,14 +241,14 @@ historyScrollBarBg: #556e837a;
historyScrollBarBgOver: #556e83bc;
historyScrollBg: #556e834c;
historyScrollBgOver: #556e836b;
msgInBg: windowBg;
msgInBg: #ffffff; // windowFg;
msgInBgSelected: #c2dcf2;
msgOutBg: #effdde;
msgOutBgSelected: #b7dbdb;
msgSelectOverlay: #358cd44c;
msgStickerOverlay: #358cd47f;
msgInServiceFg: windowActiveTextFg;
msgInServiceFgSelected: windowActiveTextFg;
msgInServiceFg: #168acd; // windowShadowFg;
msgInServiceFgSelected: #168acd; // windowShadowFg;
msgOutServiceFg: #3a8e26;
msgOutServiceFgSelected: #367570;
msgInShadow: #748ea229;
@ -259,25 +259,25 @@ msgInDateFg: #a0acb6;
msgInDateFgSelected: #6a9cc5;
msgOutDateFg: #6cc264;
msgOutDateFgSelected: #50a79c;
msgServiceFg: windowFgActive;
msgServiceFg: #ffffff; // windowActiveTextFg;
msgServiceBg: #556e837f;
msgServiceBgSelected: #8ca0b3a2;
msgInReplyBarColor: activeLineFg;
msgInReplyBarSelColor: activeLineFg;
msgOutReplyBarColor: historyOutIconFg;
msgOutReplyBarSelColor: historyOutIconFgSelected;
msgImgReplyBarColor: msgServiceFg;
msgInReplyBarColor: #37a1de; // activeLineFgError;
msgInReplyBarSelColor: #37a1de; // activeLineFgError;
msgOutReplyBarColor: #5dc452; // historyOutIconFgSelected;
msgOutReplyBarSelColor: #4da79f; // historyIconFgInverted;
msgImgReplyBarColor: #ffffff; // msgServiceBg;
msgInMonoFg: #4e7391;
msgOutMonoFg: #469165;
msgDateImgFg: msgServiceFg;
msgDateImgFg: #ffffff; // msgServiceBg;
msgDateImgBg: #00000054;
msgDateImgBgOver: #00000074;
msgDateImgBgSelected: #1c4a7187;
msgFileThumbLinkInFg: lightButtonFg;
msgFileThumbLinkInFgSelected: lightButtonFgOver;
msgFileThumbLinkInFg: lightButtonFgOver;
msgFileThumbLinkInFgSelected: #168acd; // attentionButtonFg;
msgFileThumbLinkOutFg: #5eba5b;
msgFileThumbLinkOutFgSelected: #31a298;
msgFileInBg: windowBgActive;
msgFileInBg: #40a7e3; // windowFgActive;
msgFileInBgOver: #4eade3;
msgFileInBgSelected: #51a3d3;
msgFileOutBg: #78c67f;
@ -299,7 +299,7 @@ msgFile4Bg: #efc274;
msgFile4BgDark: #e6a561;
msgFile4BgOver: #dc9c5a;
msgFile4BgSelected: #b19d84;
msgWaveformInActive: windowBgActive;
msgWaveformInActive: #40a7e3; // windowFgActive;
msgWaveformInActiveSelected: #51a3d3;
msgWaveformInInactive: #d4dee6;
msgWaveformInInactiveSelected: #9cc1e1;
@ -308,81 +308,81 @@ msgWaveformOutActiveSelected: #6badad;
msgWaveformOutInactive: #b3e2b4;
msgWaveformOutInactiveSelected: #91c3c3;
msgBotKbOverBgAdd: #ffffff20;
msgBotKbIconFg: msgServiceFg;
msgBotKbIconFg: #ffffff; // msgServiceBg;
msgBotKbRippleBg: #00000020;
mediaInFg: msgInDateFg;
mediaInFgSelected: msgInDateFgSelected;
mediaOutFg: msgOutDateFg;
mediaOutFgSelected: msgOutDateFgSelected;
mediaInFg: #a0acb6; // msgInDateFgSelected;
mediaInFgSelected: #6a9cc5; // msgOutDateFg;
mediaOutFg: #6cc264; // msgOutDateFgSelected;
mediaOutFgSelected: #50a79c; // msgServiceFg;
youtubePlayIconBg: #e83131c8;
youtubePlayIconFg: windowFgActive;
youtubePlayIconFg: #ffffff; // windowActiveTextFg;
videoPlayIconBg: #0000007f;
videoPlayIconFg: #ffffff;
toastBg: #000000b2;
toastFg: windowFgActive;
reportSpamBg: emojiPanHeaderBg;
reportSpamFg: windowFg;
toastFg: #ffffff; // windowActiveTextFg;
reportSpamBg: #fffffff2; // stickerPanDeleteBg;
reportSpamFg: #000000; // windowBgOver;
historyToDownShadow: #00000040;
historyComposeAreaBg: msgInBg;
historyComposeAreaFg: historyTextInFg;
historyComposeAreaFgService: msgInDateFg;
historyComposeIconFg: menuIconFg;
historyComposeIconFgOver: menuIconFgOver;
historySendIconFg: windowBgActive;
historySendIconFgOver: windowBgActive;
historyPinnedBg: historyComposeAreaBg;
historyReplyBg: historyComposeAreaBg;
historyReplyCancelFg: cancelIconFg;
historyReplyCancelFgOver: cancelIconFgOver;
historyComposeButtonBg: historyComposeAreaBg;
historyComposeButtonBgOver: windowBgOver;
historyComposeButtonBgRipple: windowBgRipple;
historyComposeAreaBg: #ffffff; // msgInBgSelected;
historyComposeAreaFg: historyTextOutFg;
historyComposeAreaFgService: #a0acb6; // msgInDateFgSelected;
historyComposeIconFg: #a8a8a8; // menuIconFgOver;
historyComposeIconFgOver: #999999; // menuSubmenuArrowFg;
historySendIconFg: #40a7e3; // windowFgActive;
historySendIconFgOver: #40a7e3; // windowFgActive;
historyPinnedBg: #ffffff; // historyComposeAreaFg;
historyReplyBg: #ffffff; // historyComposeAreaFg;
historyReplyCancelFg: #a8a8a8; // cancelIconFgOver;
historyReplyCancelFgOver: #999999; // boxBg;
historyComposeButtonBg: #ffffff; // historyComposeAreaFg;
historyComposeButtonBgOver: #f1f1f1; // windowBgRipple;
historyComposeButtonBgRipple: #e5e5e5; // windowFgOver;
overviewCheckBg: #00000040;
overviewCheckFg: windowBg;
overviewCheckFgActive: windowBg;
overviewCheckFg: #ffffff; // windowFg;
overviewCheckFgActive: #ffffff; // windowFg;
overviewPhotoSelectOverlay: #40ace333;
profileStatusFgOver: #7c99b2;
notificationsBoxMonitorFg: windowFg;
notificationsBoxScreenBg: dialogsBgActive;
notificationSampleUserpicFg: windowBgActive;
notificationSampleCloseFg: #d7d7d7; // windowSubTextFg;
notificationSampleTextFg: #d7d7d7; // windowSubTextFg;
notificationSampleNameFg: #939393; // windowSubTextFg;
mainMenuBg: windowBg;
mainMenuCoverBg: dialogsBgActive;
mainMenuCoverFg: windowFgActive;
mediaPlayerBg: windowBg;
mediaPlayerActiveFg: windowBgActive;
mediaPlayerInactiveFg: sliderBgInactive;
notificationsBoxMonitorFg: #000000; // windowBgOver;
notificationsBoxScreenBg: #419fd9; // dialogsNameFgActive;
notificationSampleUserpicFg: #40a7e3; // windowFgActive;
notificationSampleCloseFg: #d7d7d7; // windowSubTextFgOver;
notificationSampleTextFg: #d7d7d7; // windowSubTextFgOver;
notificationSampleNameFg: #939393; // windowSubTextFgOver;
mainMenuBg: #ffffff; // windowFg;
mainMenuCoverBg: #419fd9; // dialogsNameFgActive;
mainMenuCoverFg: #ffffff; // windowActiveTextFg;
mediaPlayerBg: #ffffff; // windowFg;
mediaPlayerActiveFg: #40a7e3; // windowFgActive;
mediaPlayerInactiveFg: #e1eaef; // sliderBgActive;
mediaPlayerDisabledFg: #9dd1ef;
mediaviewFileBg: windowBg;
mediaviewFileNameFg: windowFg;
mediaviewFileSizeFg: windowSubTextFg;
mediaviewFileBg: #ffffff; // windowFg;
mediaviewFileNameFg: #000000; // windowBgOver;
mediaviewFileSizeFg: #999999; // windowSubTextFgOver;
mediaviewFileRedCornerFg: #d55959;
mediaviewFileYellowCornerFg: #e8a659;
mediaviewFileGreenCornerFg: #49a957;
mediaviewFileBlueCornerFg: #599dcf;
mediaviewFileExtFg: activeButtonFg;
mediaviewFileExtFg: activeButtonFgOver;
mediaviewMenuBg: #383838;
mediaviewMenuBgOver: #505050;
mediaviewMenuBgRipple: #676767;
mediaviewMenuFg: windowFgActive;
mediaviewMenuFg: #ffffff; // windowActiveTextFg;
mediaviewBg: #222222eb;
mediaviewVideoBg: imageBg;
mediaviewVideoBg: #000000; // imageBgTransparent;
mediaviewControlBg: #0000003c;
mediaviewControlFg: windowFgActive;
mediaviewControlFg: #ffffff; // windowActiveTextFg;
mediaviewCaptionBg: #11111180;
mediaviewCaptionFg: mediaviewControlFg;
mediaviewCaptionFg: #ffffff; // mediaviewCaptionBg;
mediaviewTextLinkFg: #91d9ff;
mediaviewSaveMsgBg: toastBg;
mediaviewSaveMsgFg: toastFg;
mediaviewSaveMsgBg: #000000b2; // toastFg;
mediaviewSaveMsgFg: #ffffff; // reportSpamBg;
mediaviewPlaybackActive: #c7c7c7;
mediaviewPlaybackInactive: #252525;
mediaviewPlaybackActiveOver: #ffffff;
mediaviewPlaybackInactiveOver: #474747;
mediaviewPlaybackProgressFg: #ffffffc7;
mediaviewPlaybackIconFg: mediaviewPlaybackActive;
mediaviewPlaybackIconFgOver: mediaviewPlaybackActiveOver;
mediaviewPlaybackIconFg: #c7c7c7; // mediaviewPlaybackInactive;
mediaviewPlaybackIconFgOver: #ffffff; // mediaviewPlaybackInactiveOver;
mediaviewTransparentBg: #ffffff;
mediaviewTransparentFg: #cccccc;
notificationBg: windowBg;
notificationBg: #ffffff; // windowFg;

View file

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

View file

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

View file

@ -2163,7 +2163,7 @@ namespace {
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();
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.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);
}
if (!cors) cors = localCors;
@ -2212,14 +2212,13 @@ namespace {
}
void createCorners() {
style::color white = { 255, 255, 255, 255 };
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) {
::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
::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) {
::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor());
@ -2295,7 +2294,7 @@ namespace {
using Update = Window::Theme::BackgroundUpdate;
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
if (update.type == Update::Type::TestingTheme) {
if (update.paletteChanged()) {
clearCorners();
createCorners();
@ -2770,7 +2769,7 @@ namespace {
if (radius == ImageRoundRadius::Large) {
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) {
@ -2787,7 +2786,8 @@ namespace {
}
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 cornerHeight = corner.p[0]->height() / cIntRetinaFactor();
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);
}
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 cornerWidth = corner.p[0]->width() / 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 i = cornersMap.find(colorKey);
if (i == cornersMap.cend()) {

View file

@ -307,16 +307,16 @@ namespace App {
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, ImageRoundCorners corners);
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);
inline void roundRect(Painter &p, const QRect &rect, 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, 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);
}
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, const 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) {
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, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) {
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);
inline void roundRect(Painter &p, const QRect &rect, 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, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
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 "window/notifications_manager.h"
#include "history/history_location_manager.h"
#include "core/task_queue.h"
namespace {
@ -364,6 +365,10 @@ void Application::closeApplication() {
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
}
void Application::onMainThreadTask() {
base::TaskQueue::ProcessMainTasks();
}
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
void Application::updateCheck() {
startUpdateCheck(false);

View file

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

View file

@ -34,9 +34,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
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)
, _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle)
, _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel, st::aboutTextStyle)
, _text3(this, 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)
, _text3(this, st::aboutLabel) {
}
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)
, _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())
, _aboutPublic(st::normalFont, 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)
, _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_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) {
}
@ -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.setPen(st::contactsStatusFg);
textstyleSet(&st::revokePublicLinkStatusStyle);
p.setTextPalette(st::revokePublicLinkStatusPalette);
row.status.drawLeftElided(p, namex, st::contactsPadding.top() + st::contactsStatusTop, namew, width());
textstyleRestore();
p.restoreTextPalette();
}
void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
@ -1232,10 +1232,8 @@ void RevokePublicLinkBox::getPublicDone(const MTPmessages_Chats &result) {
ChatRow row;
row.peer = peer;
row.name.setText(st::contactsNameFont, peer->name, _textNameOptions);
textstyleSet(&st::revokePublicLinkStatusStyle);
row.status.setText(st::normalFont, qsl("telegram.me/") + textcmdLink(1, peer->userName()), _textDlgOptions);
textstyleRestore();
row.name.setText(st::contactsNameStyle, peer->name, _textNameOptions);
row.status.setText(st::defaultTextStyle, qsl("telegram.me/") + textcmdLink(1, peer->userName()), _textDlgOptions);
_rows.push_back(std_::move(row));
}
}

View file

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

View file

@ -30,19 +30,9 @@ boxButtonFont: font(boxFontSize semibold);
defaultBoxButton: RoundButton(defaultLightButton) {
width: -24px;
height: 36px;
padding: margins(0px, 0px, 0px, 0px);
textTop: 8px;
font: boxButtonFont;
ripple: RippleAnimation(defaultRippleAnimation) {
color: lightButtonBgRipple;
}
}
cancelBoxButton: defaultBoxButton;
attentionBoxButton: RoundButton(defaultBoxButton) {
textFg: attentionButtonFg;
textFgOver: attentionButtonFgOver;
@ -118,8 +108,12 @@ boxMediumSkip: 20px;
boxButtonPadding: margins(8px, 12px, 13px, 12px);
boxLayerButtonPadding: margins(8px, 8px, 8px, 8px);
boxLabel: FlatLabel(defaultFlatLabel) {
font: font(boxFontSize);
align: align(topleft);
style: TextStyle(defaultTextStyle) {
font: font(boxFontSize);
linkFont: font(boxFontSize);
linkFontOver: font(boxFontSize underline);
}
}
countryRowHeight: 36px;
@ -153,14 +147,17 @@ cropSkip: 13px;
cropMinSize: 20px;
confirmInviteTitle: FlatLabel(defaultFlatLabel) {
font: font(16px semibold);
align: align(center);
width: 320px;
maxHeight: 24px;
textFg: windowBoldFg;
style: TextStyle(defaultTextStyle) {
font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
}
confirmInviteStatus: FlatLabel(defaultFlatLabel) {
font: font(boxFontSize);
confirmInviteStatus: FlatLabel(boxLabel) {
align: align(center);
width: 320px;
maxHeight: 20px;
@ -174,7 +171,6 @@ confirmInviteUserHeight: 84px;
confirmInviteUserPhotoSize: 56px;
confirmInviteUserPhotoTop: 166px;
confirmInviteUserName: FlatLabel(defaultFlatLabel) {
font: normalFont;
align: align(center);
width: 66px;
maxHeight: 20px;
@ -187,16 +183,12 @@ confirmPhoneAboutLabel: FlatLabel(defaultFlatLabel) {
confirmPhoneCodeField: InputField(defaultInputField) {
}
revokePublicLinkStatusStyle: TextStyle(defaultTextStyle) {
revokePublicLinkStatusPalette: TextPalette(defaultTextPalette) {
linkFg: contactsStatusFgOnline;
linkFgDown: contactsStatusFgOnline;
linkFlagsOver: font(fsize);
}
aboutRevokePublicLabel: FlatLabel(defaultFlatLabel) {
font: normalFont;
align: align(topleft);
width: 320px;
textFg: windowFg;
}
contactUserIcon: icon {{ "add_contact_user", menuIconFg }};
@ -228,7 +220,11 @@ contactPhoneSkip: 30px;
contactsPhotoSize: 42px;
contactsPadding: margins(16px, 7px, 16px, 7px);
contactsNameTop: 2px;
contactsNameFont: semiboldFont;
contactsNameStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: semiboldFont;
}
contactsStatusTop: 23px;
contactsStatusFont: font(fsize);
contactsCheckPosition: point(8px, 16px);
@ -255,7 +251,7 @@ contactsMultiSelect: MultiSelect {
padding: margins(6px, 7px, 12px, 0px);
maxWidth: 128px;
height: 32px;
font: normalFont;
style: defaultTextStyle;
textBg: contactsBgOver;
textFg: windowFg;
textActiveBg: activeButtonBg;
@ -345,7 +341,11 @@ sharePhotoCheckbox: RoundImageCheckbox(contactsPhotoCheckbox) {
imageRadius: 28px;
imageSmallRadius: 24px;
}
shareNameFont: font(11px);
shareNameStyle: TextStyle(defaultTextStyle) {
font: font(11px);
linkFont: font(11px);
linkFontOver: font(11px);
}
shareNameFg: windowFg;
shareNameActiveFg: windowActiveTextFg;
shareNameTop: 6px;
@ -460,12 +460,11 @@ aboutVersionLink: LinkButton(defaultLinkButton) {
aboutTextTop: 34px;
aboutSkip: 14px;
aboutLabel: FlatLabel(defaultFlatLabel) {
font: normalFont;
width: 330px;
align: align(topleft);
}
aboutTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 22px;
style: TextStyle(defaultTextStyle) {
lineHeight: 22px;
}
}
autoDownloadTopDelta: 10px;
@ -513,10 +512,16 @@ backgroundScroll: ScrollArea(boxLayerScroll) {
deltab: 10px;
}
passcodeTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 20px;
}
usernamePadding: margins(23px, 6px, 21px, 12px);
usernameSkip: 49px;
usernameTextStyle: TextStyle(defaultTextStyle) {
lineHeight: 20px;
usernameTextStyle: TextStyle(passcodeTextStyle) {
font: boxTextFont;
linkFont: boxTextFont;
linkFontOver: font(boxFontSize underline);
}
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) {
return base::lambda_guarded(this, [this, closedCallback] {
auto callback = closedCallback;
return base::lambda_guarded(this, [this, callback] {
closeBox();
if (closedCallback) {
closedCallback();
if (callback) {
callback();
}
});
}
void ConfirmBox::init(const QString &text) {
textstyleSet(&st::boxTextStyle);
_text.setText(st::boxTextFont, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
textstyleRestore();
_text.setText(st::boxTextStyle, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);
}
void ConfirmBox::prepare() {
@ -125,11 +124,9 @@ void ConfirmBox::prepare() {
}
void ConfirmBox::textUpdated() {
textstyleSet(&st::boxTextStyle);
_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxPadding.bottom());
textstyleRestore();
setMouseTracking(_text.hasLinks());
}
@ -192,9 +189,7 @@ void ConfirmBox::updateLink() {
void ConfirmBox::updateHover() {
QPoint m(mapFromGlobal(_lastMousePos));
textstyleSet(&st::boxTextStyle);
auto state = _text.getStateLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width());
textstyleRestore();
ClickHandler::setActive(state.link, this);
}
@ -214,9 +209,7 @@ void ConfirmBox::paintEvent(QPaintEvent *e) {
// draw box title / text
p.setPen(st::boxTextFg);
textstyleSet(&st::boxTextStyle);
_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)) {
@ -226,7 +219,7 @@ InformBox::InformBox(QWidget*, const QString &text, const QString &doneText, bas
}
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) {
}
@ -309,13 +302,11 @@ void ConvertToSupergroupBox::prepare() {
addButton(lang(lng_profile_convert_confirm), [this] { convertToSupergroup(); });
addButton(lang(lng_cancel), [this] { closeBox(); });
textstyleSet(&st::boxTextStyle);
_text.setText(st::boxTextFont, text.join('\n'), _confirmBoxTextOptions);
_note.setText(st::boxTextFont, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_text.setText(st::boxTextStyle, text.join('\n'), _confirmBoxTextOptions);
_note.setText(st::boxTextStyle, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
_textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
_textHeight = _text.countHeight(_textWidth);
setDimensions(st::boxWideWidth, _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth));
textstyleRestore();
}
void ConvertToSupergroupBox::convertToSupergroup() {
@ -368,10 +359,8 @@ void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
// draw box title / text
p.setPen(st::boxTextFg);
textstyleSet(&st::boxTextStyle);
_text.drawLeft(p, st::boxPadding.left(), 0, _textWidth, width());
_note.drawLeft(p, st::boxPadding.left(), _textHeight + st::boxPadding.bottom(), _textWidth, width());
textstyleRestore();
}
PinMessageBox::PinMessageBox(QWidget*, ChannelData *channel, MsgId msgId)

View file

@ -562,8 +562,8 @@ ContactsBox::Inner::Inner(QWidget *parent, ChatData *chat, MembersFilter members
, _membersFilter(membersFilter)
, _allAdmins(this, lang(lng_chat_all_members_admins), !_chat->adminsEnabled(), st::defaultBoxCheckbox)
, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.right())
, _aboutAllAdmins(st::normalFont, lang(lng_chat_about_all_admins), _defaultOptions, _aboutWidth)
, _aboutAdmins(st::normalFont, lang(lng_chat_about_admins), _defaultOptions, _aboutWidth)
, _aboutAllAdmins(st::defaultTextStyle, lang(lng_chat_about_all_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))
, _contacts((membersFilter == MembersFilter::Recent) ? App::main()->contactsList() : _customList.get())
, _addContactLnk(this, lang(lng_add_contact_button)) {
@ -640,8 +640,7 @@ void ContactsBox::Inner::init() {
using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme
|| update.type == Update::Type::RevertingTheme) {
if (update.paletteChanged()) {
invalidateCache();
}
});
@ -897,7 +896,7 @@ ContactsBox::Inner::ContactData *ContactsBox::Inner::contactData(Dialogs::Row *r
if (usingMultiSelect() && _checkedContacts.contains(peer)) {
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()) {
data->statusText = App::onlineText(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)) {
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();
_byUsernameFiltered.push_back(peer);

View file

@ -374,7 +374,7 @@ void MembersBox::Inner::refresh() {
resize(width(), st::membersMarginTop + st::noContactsHeight + st::membersMarginBottom);
_aboutHeight = 0;
} 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();
if (_filter != MembersFilter::Recent || (_rows.size() >= _channel->membersCount() && _rows.size() < Global::ChatSizeMax())) {
_aboutHeight = 0;
@ -420,7 +420,7 @@ MembersBox::Inner::MemberData *MembersBox::Inner::data(int32 index) {
return result;
}
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();
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);
@ -496,7 +496,7 @@ void MembersBox::Inner::onPeerNameChanged(PeerData *peer, const PeerData::Names
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
if (_rows.at(i) == peer) {
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);
} else {
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))
, _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email))
, _recover(this, lang(lng_signin_recover)) {
textstyleSet(&st::usernameTextStyle);
if (!hint.isEmpty()) _hintText.setText(st::normalFont, lng_signin_hint(lt_password_hint, hint));
textstyleRestore();
if (!hint.isEmpty()) _hintText.setText(st::passcodeTextStyle, lng_signin_hint(lt_password_hint, hint));
}
void PasscodeBox::prepare() {
addButton(lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), [this] { onSave(); });
addButton(lang(lng_cancel), [this] { closeBox(); });
textstyleSet(&st::usernameTextStyle);
_about.setRichText(st::normalFont, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about));
_about.setRichText(st::passcodeTextStyle, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about));
_aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5);
textstyleRestore();
if (_turningOff) {
_oldPasscode->show();
setTitle(lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove));
@ -146,8 +142,6 @@ void PasscodeBox::paintEvent(QPaintEvent *e) {
Painter p(this);
textstyleSet(&st::usernameTextStyle);
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();
p.setPen(st::boxTextFg);
@ -171,8 +165,6 @@ void PasscodeBox::paintEvent(QPaintEvent *e) {
p.setPen(st::boxTextFgError);
p.drawText(QRect(st::boxPadding.left(), _recoverEmail->y() + _recoverEmail->height(), w, st::passcodeTextLine), _emailError, style::al_left);
}
textstyleRestore();
}
void PasscodeBox::resizeEvent(QResizeEvent *e) {

View file

@ -102,14 +102,14 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &filepath, QImage image, Comp
if (_preview.isNull()) {
if (filepath.isEmpty()) {
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());
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
_fileIsImage = true;
} else {
auto fileinfo = QFileInfo(filepath);
auto filename = fileinfo.fileName();
_nameText.setText(st::semiboldFont, filename, _textNameOptions);
_nameText.setText(st::semiboldTextStyle, filename, _textNameOptions);
_statusText = formatSizeText(fileinfo.size());
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
_fileIsImage = fileIsImage(filename, mimeTypeForFile(fileinfo).name());
@ -127,7 +127,7 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstn
: _contactPhone(phone)
, _contactFirstName(firstname)
, _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;
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
}
@ -400,9 +400,9 @@ EditCaptionBox::EditCaptionBox(QWidget*, HistoryItem *msg)
if (doc) {
if (doc->voice()) {
_name.setText(st::semiboldFont, lang(lng_media_audio), _textNameOptions);
_name.setText(st::semiboldTextStyle, lang(lng_media_audio), _textNameOptions);
} else {
_name.setText(st::semiboldFont, documentName(doc), _textNameOptions);
_name.setText(st::semiboldTextStyle, documentName(doc), _textNameOptions);
}
_status = formatSizeText(doc->size);
_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;
subscribe(Window::Theme::Background(), [this](const Update &update) {
if (update.type == Update::Type::TestingTheme
|| update.type == Update::Type::RevertingTheme) {
if (update.paletteChanged()) {
invalidateCache();
}
});
@ -362,7 +361,7 @@ void ShareBox::Inner::updateChat(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) {
@ -600,7 +599,7 @@ void ShareBox::Inner::updateUpon(const QPoint &pos) {
auto left = _rowsLeft + qFloor(column * _rowWidthReal) + st::shareColumnSkip / 2;
auto top = _rowsTop + row * _rowHeight + st::sharePhotoTop;
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;
if (upon >= displayedChatsCount()) {
upon = -1;

View file

@ -148,7 +148,7 @@ StickersBox::StickersBox(QWidget*, const Stickers::Order &archivedIds)
: _section(Section::ArchivedPart)
, _archived(0, this, archivedIds)
, _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) {
@ -691,7 +691,7 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
int statusx = namex;
int statusy = st::contactsPadding.top() + st::contactsStatusTop;
p.setFont(st::contactsNameFont);
p.setFont(st::contactsNameStyle.font);
p.setPen(st::contactsNameFg);
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 {
auto result = set.title;
int titleWidth = st::contactsNameFont->width(result);
int titleWidth = st::contactsNameStyle.font->width(result);
if (titleWidth > maxNameWidth) {
result = st::contactsNameFont->elided(result, maxNameWidth);
titleWidth = st::contactsNameFont->width(result);
result = st::contactsNameStyle.font->elided(result, maxNameWidth);
titleWidth = st::contactsNameStyle.font->width(result);
}
if (outTitleWidth) {
*outTitleWidth = titleWidth;

View file

@ -49,10 +49,8 @@ void UsernameBox::prepare() {
connect(_username, SIGNAL(submitted(bool)), this, SLOT(onSave()));
connect(_link, SIGNAL(clicked()), this, SLOT(onLinkClick()));
textstyleSet(&st::usernameTextStyle);
_about.setRichText(st::boxTextFont, lang(lng_username_about));
_about.setRichText(st::usernameTextStyle, 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());
textstyleRestore();
_checkTimer->setSingleShot(true);
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.setPen(st::boxTextFg);
textstyleSet(&st::usernameTextStyle);
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());
textstyleRestore();
int32 linky = _username->y() + _username->height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
if (_link->isHidden()) {
@ -102,9 +98,7 @@ void UsernameBox::resizeEvent(QResizeEvent *e) {
_username->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _username->height());
_username->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top());
textstyleSet(&st::usernameTextStyle);
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);
_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 {
auto copy = value.copyOf();
if (!copy.isEmpty()) {
auto result = "st::" + copy.back();
// Copy is disabled for colors.
if (value.type().tag == Tag::Color || value.type().tag == Tag::Struct) {
result += ".clone()";
}
return result;
return "st::" + copy.back();
}
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::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;
case Tag::Point: {
auto v(value.Point());
@ -449,9 +450,13 @@ public:\n\
\n\
// Created not inited, should be finalized before usage.\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 {
auto name = variable.name.back();
if (variable.value.type().tag != structure::TypeTag::Color) {
@ -459,7 +464,7 @@ public:\n\
}
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 false;
@ -468,7 +473,7 @@ public:\n\
\n\
palette &operator=(const palette &other) {\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 (_status[i] == Status::Initial) {\n\
new (data(i)) internal::ColorData(*other.data(i));\n\
@ -494,8 +499,10 @@ public:\n\
}\n\
\n\
private:\n\
static constexpr auto kCount = " << count << ";\n\
\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\
data(i)->~ColorData();\n\
_status[i] = Status::Initial;\n\
@ -540,15 +547,15 @@ private:\n\
Loaded,\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\
color _colors[" << count << "] = {\n";
color _colors[kCount] = {\n";
for (int i = 0; i != count; ++i) {
header_->stream() << "\t\tdata(" << i << "),\n";
}
header_->stream() << "\
};\n\
Status _status[" << count << "] = { Status::Initial };\n\
Status _status[kCount] = { Status::Initial };\n\
bool _ready = false;\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\
void apply(const palette &other);\n\
void reset();\n\
int indexOfColor(color c);\n\
\n\
} // namespace main_palette\n";
header_->newline();
return true;
}
@ -601,21 +607,8 @@ bool Generator::writeStructsDefinitions() {
}
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() << "\
struct " << value.name.back() << " {\n\
" << value.name.back() << " clone() const {\n\
return { " << fields.join(", ") << " };\n\
}\n";
if (!fields.empty()) header_->newline();
struct " << value.name.back() << " {\n";
for (auto &field : value.fields) {
auto type = typeToString(field.type);
if (type.isEmpty()) {
@ -638,6 +631,9 @@ bool Generator::writeRefsDeclarations() {
header_->pushNamespace("st");
if (isPalette_) {
header_->stream() << "extern const style::color &transparent; // special color\n";
}
bool result = module_.enumVariables([this](const Variable &value) -> bool {
auto name = value.name.back();
auto type = typeToString(value.value.type());
@ -699,6 +695,9 @@ bool Generator::writeRefsDefinition() {
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 {
auto name = variable.name.back();
auto type = typeToString(variable.value.type());
@ -707,7 +706,7 @@ bool Generator::writeRefsDefinition() {
}
source_->stream() << "const " << type << " &" << name << "(";
if (isPalette_) {
source_->stream() << "_palette." << name << "()";
source_->stream() << "_palette.get_" << name << "()";
} else {
source_->stream() << "_" << name;
}
@ -719,13 +718,30 @@ bool Generator::writeRefsDefinition() {
bool Generator::writeSetPaletteColor() {
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\
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;
checksumString.append("&transparent:{ 255, 255, 255, 0 }");
bool result = module_.enumVariables([this, &indexInPalette, &checksumString](const Variable &variable) -> bool {
auto name = variable.name.back();
auto index = indexInPalette++;
@ -735,8 +751,9 @@ void palette::finalize() {\n\
}
auto color = variable.value.Color();
auto fallbackIndex = paletteIndices_.value(colorFallbackName(variable.value), -1);
source_->stream() << "\tcompute(" << index << ", " << fallbackIndex << ", {" << color.red << ", " << color.green << ", " << color.blue << ", " << color.alpha << "});\n";
checksumString.append('&' + name + ':' + valueAssignmentCode(variable.value));
auto assignment = QString("{ %1, %2, %3, %4 }").arg(color.red).arg(color.green).arg(color.blue).arg(color.alpha);
source_->stream() << "\tcompute(" << index << ", " << fallbackIndex << ", " << assignment << ");\n";
checksumString.append('&' + name + ':' + assignment);
return true;
});
auto count = indexInPalette;
@ -888,6 +905,10 @@ void reset() {\n\
style::internal::resetIcons();\n\
}\n\
\n\
int indexOfColor(color c) {\n\
return _palette.indexOfColor(c);\n\
}\n\
\n\
} // namespace main_palette\n\
\n";
@ -1226,8 +1247,12 @@ bool Generator::writeSampleTheme(const QString &filepath) {
return false;
}
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 colorString = paletteColorValue(color);
if (fallbackIndex >= 0) {
auto fallbackVariable = module_.findVariableInModule(names[fallbackIndex], module_);
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;
//
// Disable large lambda support.
// If you really need it, just store data in some std_::unique_ptr<struct>.
//
//template <typename Lambda, typename Return, typename ...Args>
//struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
// using JustLambda = std_::decay_simple_t<Lambda>;
// using LambdaPtr = std_::unique_ptr<JustLambda>;
// using Parent = lambda_wrap_helper_base<Return, Args...>;
// static void construct_move_other_method(void *lambda, void *source) {
// auto source_lambda = static_cast<LambdaPtr*>(source);
// new (lambda) LambdaPtr(std_::move(*source_lambda));
// }
// static void construct_move_lambda_method(void *lambda, void *source) {
// auto source_lambda = static_cast<JustLambda*>(source);
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
// }
// static Return call_method(const void *lambda, Args... args) {
// return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...);
// }
// static void destruct_method(const void *lambda) {
// static_cast<const LambdaPtr*>(lambda)->~LambdaPtr();
// }
// lambda_wrap_helper_move_impl() : Parent(
// &Parent::bad_construct_copy,
// &lambda_wrap_helper_move_impl::construct_move_other_method,
// &lambda_wrap_helper_move_impl::call_method,
// &lambda_wrap_helper_move_impl::destruct_method) {
// }
//
//protected:
// lambda_wrap_helper_move_impl(
// typename Parent::construct_copy_other_type construct_copy_other
// ) : Parent(
// 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>
struct lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_base<Return, Args...> {
using JustLambda = std_::decay_simple_t<Lambda>;
using LambdaPtr = std_::unique_ptr<JustLambda>;
using Parent = lambda_wrap_helper_base<Return, Args...>;
static void construct_move_other_method(void *lambda, void *source) {
auto source_lambda = static_cast<LambdaPtr*>(source);
new (lambda) LambdaPtr(std_::move(*source_lambda));
}
static void construct_move_lambda_method(void *lambda, void *source) {
auto source_lambda = static_cast<JustLambda*>(source);
new (lambda) LambdaPtr(std_::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
}
static Return call_method(const void *lambda, Args... args) {
return (**static_cast<const LambdaPtr*>(lambda))(std_::forward<Args>(args)...);
}
static void destruct_method(const void *lambda) {
static_cast<const LambdaPtr*>(lambda)->~LambdaPtr();
}
lambda_wrap_helper_move_impl() : Parent(
&Parent::bad_construct_copy,
&lambda_wrap_helper_move_impl::construct_move_other_method,
&lambda_wrap_helper_move_impl::call_method,
&lambda_wrap_helper_move_impl::destruct_method) {
}
protected:
lambda_wrap_helper_move_impl(
typename Parent::construct_copy_other_type construct_copy_other
) : Parent(
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>
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;
//
// Disable large lambda support.
// If you really need it, just store data in some QSharedPointer<struct>.
//
//template <typename Lambda, typename Return, typename ...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...> {
// using JustLambda = std_::decay_simple_t<Lambda>;
// using LambdaPtr = std_::unique_ptr<JustLambda>;
// using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>;
// static void construct_copy_other_method(void *lambda, const void *source) {
// auto source_lambda = static_cast<const LambdaPtr*>(source);
// new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get()));
// }
// static void construct_copy_lambda_method(void *lambda, const void *source) {
// 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>
struct lambda_wrap_helper_copy_impl<Lambda, std_::true_type, Return, Args...> : public lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...> {
using JustLambda = std_::decay_simple_t<Lambda>;
using LambdaPtr = std_::unique_ptr<JustLambda>;
using Parent = lambda_wrap_helper_move_impl<Lambda, std_::true_type, Return, Args...>;
static void construct_copy_other_method(void *lambda, const void *source) {
auto source_lambda = static_cast<const LambdaPtr*>(source);
new (lambda) LambdaPtr(std_::make_unique<JustLambda>(*source_lambda->get()));
}
static void construct_copy_lambda_method(void *lambda, const void *source) {
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>
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>
struct lambda_type_resolver<R(Lambda::*)(Args...) const> {
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>

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
*/
using "basic.style";
using "basic_types.style";
using "ui/widgets/widgets.style";
@ -32,6 +31,11 @@ dialogsRippleBg: windowBgRipple;
dialogsRippleBgActive: activeButtonBgRipple;
dialogsTextFont: font(fsize);
dialogsTextStyle: TextStyle(defaultTextStyle) {
font: dialogsTextFont;
linkFont: dialogsTextFont;
linkFontOver: dialogsTextFont;
}
dialogsDateFont: font(13px);
dialogsDateSkip: 5px;
dialogsNameTop: 2px;
@ -55,30 +59,23 @@ dialogsScroll: ScrollArea(defaultScrollArea) {
bottomsh: 0px;
}
dialogsTextStyle: TextStyle(defaultTextStyle) {
dialogsTextPalette: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgService;
linkFgDown: dialogsTextFgService;
linkFlagsOver: font(fsize);
}
dialogsTextStyleOver: TextStyle(dialogsTextStyle) {
dialogsTextPaletteOver: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgServiceOver;
linkFgDown: dialogsTextFgServiceOver;
}
dialogsTextStyleActive: TextStyle(dialogsTextStyle) {
dialogsTextPaletteActive: TextPalette(defaultTextPalette) {
linkFg: dialogsTextFgServiceActive;
linkFgDown: dialogsTextFgServiceActive;
}
dialogsTextStyleDraft: TextStyle(dialogsTextStyle) {
dialogsTextPaletteDraft: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFg;
linkFgDown: dialogsDraftFg;
}
dialogsTextStyleDraftOver: TextStyle(dialogsTextStyle) {
dialogsTextPaletteDraftOver: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFgOver;
linkFgDown: dialogsDraftFgOver;
}
dialogsTextStyleDraftActive: TextStyle(dialogsTextStyle) {
dialogsTextPaletteDraftActive: TextPalette(defaultTextPalette) {
linkFg: dialogsDraftFgActive;
linkFgDown: dialogsDraftFgActive;
}
dialogsMenuToggle: IconButton {

View file

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

View file

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

View file

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

View file

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

View file

@ -339,7 +339,7 @@ public:
void unregSendAction(UserData *from);
bool updateSendActionNeedsAnimating(UserData *user, const MTPSendMessageAction &action);
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();

View file

@ -346,7 +346,11 @@ botKbBg: menuBgOver;
botKbOverBg: menuBgOver;
botKbDownBg: menuBgRipple;
botKbColor: windowBoldFgOver;
botKbFont: font(15px semibold);
botKbStyle: TextStyle(defaultTextStyle) {
font: font(15px semibold);
linkFont: font(15px semibold);
linkFontOver: font(15px semibold);
}
botKbButton: BotKeyboardButton {
margin: 10px;
padding: 10px;
@ -404,3 +408,26 @@ historyUnreadBarFont: semiboldFont;
historyForwardChooseMargins: margins(30px, 10px, 30px, 10px);
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;
button.type = row.at(j).type;
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();
}
_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();
if (tw >= st::botKbFont->elidew + _st->padding * 2) {
if (tw >= st::botKbStyle.font->elidew + _st->padding * 2) {
tx += _st->padding;
tw -= _st->padding * 2;
} else if (tw > st::botKbFont->elidew) {
tx += (tw - st::botKbFont->elidew) / 2;
tw = st::botKbFont->elidew;
} else if (tw > st::botKbStyle.font->elidew) {
tx += (tw - st::botKbStyle.font->elidew) / 2;
tw = st::botKbStyle.font->elidew;
}
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 {
if (cacheFor != this) {
cacheFor = this;
cache.setText(st::dialogsTextFont, inDialogsText(), _textDlgOptions);
cache.setText(st::dialogsTextStyle, inDialogsText(), _textDlgOptions);
}
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.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
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 style::font textFont() const = 0;
virtual const style::TextStyle &textStyle() const = 0;
int buttonSkip() 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()) {
setLinks(MakeShared<PhotoOpenClickHandler>(_data), MakeShared<PhotoSaveClickHandler>(_data), MakeShared<PhotoCancelClickHandler>(_data));
if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
_caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
}
init();
}
@ -597,7 +597,7 @@ HistoryVideo::HistoryVideo(HistoryItem *parent, DocumentData *document, const QS
, _thumbw(1)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
_caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
}
setDocumentLinks(_data);
@ -900,10 +900,14 @@ ImagePtr HistoryVideo::replyPreview() {
return _data->replyPreview;
}
HistoryDocumentCaptioned::HistoryDocumentCaptioned()
: _caption(st::msgFileMinWidth - st::msgPadding.left() - st::msgPadding.right()) {
}
HistoryDocumentVoicePlayback::HistoryDocumentVoicePlayback(const HistoryDocument *that)
: _position(0)
, a_progress(0., 0.)
, _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
: a_progress(0., 0.)
, _a_progress(animation(const_cast<HistoryDocument*>(that), &HistoryDocument::step_voiceProgress)) {
}
void HistoryDocumentVoice::ensurePlayback(const HistoryDocument *that) const {
@ -932,7 +936,7 @@ HistoryDocument::HistoryDocument(HistoryItem *parent, DocumentData *document, co
setStatusSize(FileStatusSizeReady);
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 {
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
}
if (!isBubbleTop()) {
_minh -= st::msgFileTopMinus;
}
if (captioned) {
auto captionw = _maxw - st::msgPadding.left() - st::msgPadding.right();
@ -1048,6 +1055,9 @@ int HistoryDocument::resizeGetHeight(int width) {
} else {
_height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
}
if (!isBubbleTop()) {
_height -= st::msgFileTopMinus;
}
auto captionw = _width - st::msgPadding.left() - st::msgPadding.right();
_height += captioned->_caption.countHeight(captionw);
if (isBubbleBottom()) {
@ -1077,18 +1087,19 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
bool showPause = updateStatusText();
bool radial = isRadialAnimation(ms);
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
int nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
if (auto thumbed = Get<HistoryDocumentThumbed>()) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop;
nametop = st::msgFileThumbNameTop - topMinus;
nameright = st::msgFileThumbPadding.left();
statustop = st::msgFileThumbStatusTop;
linktop = st::msgFileThumbLinkTop;
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
statustop = st::msgFileThumbStatusTop - topMinus;
linktop = st::msgFileThumbLinkTop - topMinus;
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus;
auto inWebPage = (_parent->getMedia() != this);
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;
if (loaded) {
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);
if (selected) {
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())) {
@ -1147,12 +1158,12 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
}
} else {
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
nametop = st::msgFileNameTop;
nametop = st::msgFileNameTop - topMinus;
nameright = st::msgFilePadding.left();
statustop = st::msgFileStatusTop;
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
statustop = st::msgFileStatusTop - topMinus;
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);
if (selected) {
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);
}
int32 namewidth = _width - nameleft - nameright;
auto namewidth = _width - nameleft - nameright;
if (auto voice = Get<HistoryDocumentVoice>()) {
const VoiceWaveform *wf = 0;
@ -1298,12 +1309,13 @@ HistoryTextState HistoryDocument::getState(int x, int y, HistoryStateRequest req
bool showPause = updateStatusText();
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (auto thumbed = Get<HistoryDocumentThumbed>()) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
linktop = st::msgFileThumbLinkTop;
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
linktop = st::msgFileThumbLinkTop - topMinus;
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)) {
result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel;
@ -1317,9 +1329,9 @@ HistoryTextState HistoryDocument::getState(int x, int y, HistoryStateRequest req
}
}
} 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)) {
result.link = (_data->loading() || _data->uploading()) ? _cancell : _savel;
return result;
@ -1477,6 +1489,10 @@ bool HistoryDocument::updateStatusText() const {
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) {
if (auto voice = Get<HistoryDocumentVoice>()) {
if (voice->_playback) {
@ -1529,7 +1545,7 @@ HistoryGif::HistoryGif(HistoryItem *parent, DocumentData *document, const QStrin
setStatusSize(FileStatusSizeReady);
if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
_caption.setText(st::messageTextStyle, caption + _parent->skipBlock(), itemTextNoMonoOptions(_parent));
}
_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)
, _userId(userId)
, _contact(0)
, _phonew(0)
, _fname(first)
, _lname(last)
, _phone(App::formatPhone(phone))
, _linkw(0) {
_name.setText(st::semiboldFont, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
, _phone(App::formatPhone(phone)) {
_name.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
_phonew = st::normalFont->width(_phone);
}
@ -2264,6 +2277,9 @@ void HistoryContact::initDimensions() {
} else {
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
}
if (!isBubbleTop()) {
_minh -= st::msgFileTopMinus;
}
_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;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (_userId) {
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop;
nametop = st::msgFileThumbNameTop - topMinus;
nameright = st::msgFileThumbPadding.left();
statustop = st::msgFileThumbStatusTop;
linktop = st::msgFileThumbLinkTop;
statustop = st::msgFileThumbStatusTop - topMinus;
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) {
_contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y());
} else {
p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % kUserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize));
}
if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners);
App::roundRect(p, rthumb, p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
}
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);
} else {
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
nametop = st::msgFileNameTop;
nametop = st::msgFileNameTop - topMinus;
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));
}
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;
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus;
if (_userId) {
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)) {
result.link = _linkl;
return result;
@ -2375,6 +2393,7 @@ void HistoryContact::updateSentMedia(const MTPMessageMedia &media) {
}
namespace {
QString siteNameFromUrl(const QString &url) {
QUrl u(url);
QString pretty = u.isValid() ? u.toDisplayString() : url;
@ -2400,6 +2419,7 @@ int32 articleThumbHeight(PhotoData *thumb, int32 width) {
}
int32 _lineHeight = 0;
} // namespace
HistoryWebPage::HistoryWebPage(HistoryItem *parent, WebPageData *data) : HistoryMedia(parent)
@ -2479,13 +2499,13 @@ void HistoryWebPage::initDimensions() {
} else if (_data->siteName == qstr("Instagram")) {
opts = &_instagramDescriptionOptions;
}
_description.setText(st::webPageDescriptionFont, text, *opts);
_description.setText(st::webPageDescriptionStyle, text, *opts);
}
if (_title.isEmpty() && !title.isEmpty()) {
if (!_asArticle && !_attach && _description.isEmpty()) {
title += _parent->skipBlock();
}
_title.setText(st::webPageTitleFont, title, _webpageTitleOptions);
_title.setText(st::webPageTitleStyle, title, _webpageTitleOptions);
}
if (!_siteNameWidth && !_data->siteName.isEmpty()) {
_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);
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;
}
@ -2943,11 +2963,11 @@ void HistoryGame::initDimensions() {
if (_description.isEmpty() && !_data->description.isEmpty()) {
auto text = _data->description;
if (!text.isEmpty()) {
_description.setText(st::webPageDescriptionFont, text, _webpageDescriptionOptions);
_description.setText(st::webPageDescriptionStyle, text, _webpageDescriptionOptions);
}
}
if (_title.isEmpty() && !title.isEmpty()) {
_title.setText(st::webPageTitleFont, title, _webpageTitleOptions);
_title.setText(st::webPageTitleStyle, title, _webpageTitleOptions);
}
// init dimensions
@ -3183,7 +3203,7 @@ TextSelection HistoryGame::adjustSelection(TextSelection selection, TextSelectTy
}
bool HistoryGame::consumeMessageText(const TextWithEntities &textWithEntities) {
_description.setMarkedText(st::webPageDescriptionFont, textWithEntities, itemTextOptions(_parent));
_description.setMarkedText(st::webPageDescriptionStyle, textWithEntities, itemTextOptions(_parent));
return true;
}
@ -3279,10 +3299,10 @@ HistoryLocation::HistoryLocation(HistoryItem *parent, const LocationCoords &coor
, _description(st::msgMinWidth)
, _link(new LocationClickHandler(coords)) {
if (!title.isEmpty()) {
_title.setText(st::webPageTitleFont, textClean(title), _webpageTitleOptions);
_title.setText(st::webPageTitleStyle, textClean(title), _webpageTitleOptions);
}
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;
};
struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned> {
Text _caption = { int(st::msgFileMinWidth) - st::msgPadding.left() - st::msgPadding.right() };
HistoryDocumentCaptioned();
Text _caption;
};
struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed> {
QString _name;
@ -305,7 +307,7 @@ class HistoryDocument;
struct HistoryDocumentVoicePlayback {
HistoryDocumentVoicePlayback(const HistoryDocument *that);
int32 _position;
int32 _position = 0;
anim::value a_progress;
BasicAnimation _a_progress;
};
@ -384,9 +386,7 @@ public:
bool customInfoLayout() const override {
return false;
}
QMargins bubbleMargins() const override {
return Get<HistoryDocumentThumbed>() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
}
QMargins bubbleMargins() const override;
bool hideForwardedFrom() const override {
return _data->song();
}
@ -631,14 +631,14 @@ public:
private:
int32 _userId;
UserData *_contact;
UserData *_contact = nullptr;
int32 _phonew;
int _phonew = 0;
QString _fname, _lname, _phone;
Text _name;
ClickHandlerPtr _linkl;
int32 _linkw;
int _linkw = 0;
QString _link;
};

View file

@ -112,7 +112,7 @@ void HistoryMessageSigned::create(UserData *from, const QDateTime &date) {
if (timew + namew > st::maxSignatureSize) {
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 {
@ -123,7 +123,7 @@ void HistoryMessageEdited::create(const QDateTime &editDate, const QDateTime &da
_editDate = editDate;
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 {
@ -151,9 +151,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
}
}
TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto };
textstyleSet(&st::inFwdTextStyle);
_text.setText(st::msgServiceNameFont, text, opts);
textstyleRestore();
_text.setText(st::fwdTextStyle, text, opts);
_text.setLink(1, (_originalId && _authorOriginal->isChannel()) ? goToMessageClickHandler(_authorOriginal, _originalId) : _authorOriginal->openLink());
if (via) {
_text.setLink(2, via->_lnk);
@ -174,7 +172,7 @@ bool HistoryMessageReply::updateData(HistoryMessage *holder, bool force) {
}
if (replyToMsg) {
replyToText.setText(st::msgFont, textClean(replyToMsg->inReplyText()), _textDlgOptions);
replyToText.setText(st::messageTextStyle, textClean(replyToMsg->inReplyText()), _textDlgOptions);
updateName();
@ -214,7 +212,7 @@ bool HistoryMessageReply::isNameUpdated() const {
void HistoryMessageReply::updateName() const {
if (replyToMsg) {
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;
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
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 {
bool selected = (flags & PaintSelected), outbg = holder->hasOutLayout();
const style::color *bar = &st::msgImgReplyBarColor;
style::color bar = st::msgImgReplyBarColor;
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));
p.fillRect(rbar, *bar);
p.fillRect(rbar, bar);
if (w > st::msgReplyBarSkip) {
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));
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
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);
}
style::font HistoryMessage::KeyboardStyle::textFont() const {
return st::msgServiceFont;
const style::TextStyle &HistoryMessage::KeyboardStyle::textStyle() const {
return st::serviceTextStyle;
}
void HistoryMessage::KeyboardStyle::repaint(const HistoryItem *item) const {
@ -1026,22 +1024,18 @@ void HistoryMessage::setText(const TextWithEntities &textWithEntities) {
if (mediaDisplayed && _media->consumeMessageText(textWithEntities)) {
setEmptyText();
} else {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
if (_media && _media->isDisplayed() && !_media->isAboveMessage()) {
_text.setMarkedText(st::msgFont, textWithEntities, itemTextOptions(this));
_text.setMarkedText(st::messageTextStyle, textWithEntities, itemTextOptions(this));
} 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;
_textHeight = 0;
}
}
void HistoryMessage::setEmptyText() {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
_text.setMarkedText(st::msgFont, { QString(), EntitiesInText() }, itemTextOptions(this));
textstyleRestore();
_text.setMarkedText(st::messageTextStyle, { QString(), EntitiesInText() }, itemTextOptions(this));
_textWidth = -1;
_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 o = p.opacity();
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);
}
}
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
p.setTextPalette(outbg ? st::outTextPalette : st::inTextPalette);
if (auto keyboard = inlineReplyKeyboard()) {
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);
}
textstyleRestore();
p.restoreTextPalette();
auto reply = Get<HistoryMessageReply>();
if (reply && reply->isNameUpdated()) {
@ -1382,9 +1376,9 @@ void HistoryMessage::paintForwardedInfo(Painter &p, QRect &trect, bool selected)
auto fwd = Get<HistoryMessageForwarded>();
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);
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));
}
@ -1478,10 +1472,8 @@ int HistoryMessage::performResizeGetHeight(int width) {
} else {
auto textWidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 1);
if (textWidth != _textWidth) {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
_textWidth = textWidth;
_textHeight = _text.countHeight(textWidth);
textstyleRestore();
}
_height = _textHeight;
}
@ -1676,9 +1668,7 @@ bool HistoryMessage::getStateForwardedInfo(int x, int y, QRect &trect, HistoryTe
if (breakEverywhere) {
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere;
}
textstyleSet(&st::inFwdTextStyle);
*outResult = fwd->_text.getState(x - trect.left(), y - trect.top(), trect.width(), textRequest);
textstyleRestore();
outResult->symbol = 0;
outResult->afterSymbol = false;
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 {
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());
textstyleRestore();
return true;
}
return false;
@ -2105,9 +2093,7 @@ QString HistoryService::inReplyText() const {
}
void HistoryService::setServiceText(const QString &text, const Links &links) {
textstyleSet(&st::serviceTextStyle);
_text.setText(st::msgServiceFont, text, _historySrvOptions);
textstyleRestore();
_text.setText(st::serviceTextStyle, text, _historySrvOptions);
for (int i = 0, count = links.size(); i != count; ++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);
if (nwidth != _textWidth) {
_textWidth = nwidth;
textstyleSet(&st::serviceTextStyle);
_textHeight = _text.countHeight(nwidth);
textstyleRestore();
}
if (width >= _maxw) {
_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 trect = outer.marginsAdded(-st::msgServicePadding);
if (trect.contains(x, y)) {
textstyleSet(&st::serviceTextStyle);
auto textRequest = request.forText();
textRequest.align = style::al_center;
result = _text.getState(x - trect.x(), y - trect.y(), trect.width(), textRequest);
textstyleRestore();
if (auto gamescore = Get<HistoryServiceGameScore>()) {
if (!result.link && result.cursor == HistoryInTextCursorState && outer.contains(x, y)) {
result.link = gamescore->lnk;

View file

@ -211,7 +211,7 @@ private:
int buttonRadius() 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;
protected:

View file

@ -196,16 +196,15 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
} else {
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 o = p.opacity();
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);
}
}
textstyleSet(&st::serviceTextStyle);
p.setTextPalette(st::serviceTextPalette);
if (auto media = message->getMedia()) {
height -= st::msgServiceMargin.top() + media->height();
@ -229,7 +228,7 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
p.setFont(st::msgServiceFont);
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) {

View file

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

View file

@ -439,7 +439,7 @@ private:
int buttonRadius() 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;
protected:

View file

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

View file

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

View file

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

View file

@ -90,7 +90,7 @@ void PhoneWidget::showSignup() {
showPhoneError(lang(lng_bad_phone_noreg));
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 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->entity()->setLink(1, MakeShared<UrlClickHandler>(qsl("https://telegram.org"), false));
_signup->entity()->setLink(2, MakeShared<LambdaClickHandler>([this] {
@ -231,7 +231,7 @@ void PhoneWidget::selectCountry(const QString &c) {
}
void PhoneWidget::setInnerFocus() {
_phone->setFocus();
_phone->setFocusFast();
}
void PhoneWidget::activate() {

View file

@ -39,7 +39,7 @@ PwdCheckWidget::PwdCheckWidget(QWidget *parent, Widget::Data *data) : Step(paren
, _hasRecovery(getData()->hasRecovery)
, _hint(getData()->pwdHint)
, _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))
, _toRecover(this, lang(lng_signin_recover))
, _toPassword(this, lang(lng_signin_try_password))
@ -77,9 +77,9 @@ void PwdCheckWidget::resizeEvent(QResizeEvent *e) {
void PwdCheckWidget::setInnerFocus() {
if (_pwdField->isHidden()) {
_codeField->setFocus();
_codeField->setFocusFast();
} else {
_pwdField->setFocus();
_pwdField->setFocusFast();
}
}

View file

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

View file

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

View file

@ -383,16 +383,6 @@ bool LayerStackWidget::layerShown() const {
void LayerStackWidget::setCacheImages() {
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();
if (_specialLayer) {
auto sides = Ui::Shadow::Side::Left | Ui::Shadow::Side::Right;
@ -408,6 +398,16 @@ void LayerStackWidget::setCacheImages() {
if (auto layer = currentLayer()) {
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());
updateLayerBoxes();
_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;
}
const style::color &documentColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFile1Bg,
&st::msgFile2Bg,
&st::msgFile3Bg,
&st::msgFile4Bg
style::color documentColor(int32 colorIndex) {
const style::color colors[] = {
st::msgFile1Bg,
st::msgFile2Bg,
st::msgFile3Bg,
st::msgFile4Bg
};
return *colors[colorIndex & 3];
return colors[colorIndex & 3];
}
const style::color &documentDarkColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFile1BgDark,
&st::msgFile2BgDark,
&st::msgFile3BgDark,
&st::msgFile4BgDark
style::color documentDarkColor(int32 colorIndex) {
static style::color colors[] = {
st::msgFile1BgDark,
st::msgFile2BgDark,
st::msgFile3BgDark,
st::msgFile4BgDark
};
return *colors[colorIndex & 3];
return colors[colorIndex & 3];
}
const style::color &documentOverColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFile1BgOver,
&st::msgFile2BgOver,
&st::msgFile3BgOver,
&st::msgFile4BgOver
style::color documentOverColor(int32 colorIndex) {
static style::color colors[] = {
st::msgFile1BgOver,
st::msgFile2BgOver,
st::msgFile3BgOver,
st::msgFile4BgOver
};
return *colors[colorIndex & 3];
return colors[colorIndex & 3];
}
const style::color &documentSelectedColor(int32 colorIndex) {
static const style::color *colors[] = {
&st::msgFile1BgSelected,
&st::msgFile2BgSelected,
&st::msgFile3BgSelected,
&st::msgFile4BgSelected
style::color documentSelectedColor(int32 colorIndex) {
static style::color colors[] = {
st::msgFile1BgSelected,
st::msgFile2BgSelected,
st::msgFile3BgSelected,
st::msgFile4BgSelected
};
return *colors[colorIndex & 3];
return colors[colorIndex & 3];
}
RoundCorners documentCorners(int32 colorIndex) {

View file

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

View file

@ -299,8 +299,8 @@ void MainWidget::updateForwardingTexts() {
text = lng_forward_messages(lt_count, _toForward.size());
}
}
_toForwardFrom.setText(st::msgServiceNameFont, from, _textNameOptions);
_toForwardText.setText(st::msgFont, textClean(text), _textDlgOptions);
_toForwardFrom.setText(st::msgNameStyle, from, _textNameOptions);
_toForwardText.setText(st::messageTextStyle, textClean(text), _textDlgOptions);
_toForwardNameVersion = version;
}
@ -1087,7 +1087,7 @@ void MainWidget::onCacheBackground() {
_cachedBackground = App::pixmapFromImageInPlace(std_::move(result));
} else {
QRect to, from;
backgroundParams(_willCacheFor, to, from);
Window::Theme::ComputeBackgroundRects(_willCacheFor, bg.size(), to, from);
_cachedX = to.x();
_cachedY = to.y();
_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();
}
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() {
_history->updateScrollColors();
}

View file

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

View file

@ -262,6 +262,7 @@ void MainWindow::setupPasscode() {
updateControlsGeometry();
if (_main) _main->hide();
_mediaView->hide();
Ui::hideSettingsAndLayer(true);
if (_intro) _intro->hide();
if (animated) {
@ -1291,7 +1292,7 @@ QImage MainWindow::iconLarge() const {
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);
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;
if (size < 0) {
size = -size;

View file

@ -144,7 +144,7 @@ public:
bool isActive(bool cached = true) const;
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(QWidget *w, QPaintEvent *e) {
@ -226,7 +226,7 @@ private:
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;
struct DelayedServiceMsg {

View file

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

View file

@ -229,7 +229,7 @@ void CoverWidget::updatePlayPrevNextPositions() {
}
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);
}

View file

@ -301,7 +301,7 @@ void Widget::updateLabelsGeometry() {
widthForName -= _timeLabel->width() + 2 * st::normalFont->spacew;
_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);
}

View file

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

View file

@ -150,3 +150,70 @@ mediaviewDropdownMenu: DropdownMenu(defaultDropdownMenu) {
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 "media/media_audio.h"
#include "history/history_media_types.h"
#include "window/window_theme_preview.h"
#include "core/task_queue.h"
namespace {
@ -71,13 +73,13 @@ MediaView::MediaView() : TWidget(App::wnd())
, _docSaveAs(this, lang(lng_mediaview_save_as), st::mediaviewFileLink)
, _docCancel(this, lang(lng_cancel), st::mediaviewFileLink)
, _radial(animation(this, &MediaView::step_radial))
, _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction)
, _lastAction(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction)
, _a_state(animation(this, &MediaView::step_state))
, _dropdown(this, st::mediaviewDropdownMenu) {
TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
_saveMsgText.setRichText(st::medviewSaveMsgFont, 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());
_saveMsgText.setRichText(st::mediaviewSaveMsgStyle, lang(lng_mediaview_saved), _textDlgOptions, custom);
_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(); }));
connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int)));
@ -132,12 +134,12 @@ void MediaView::moveToScreen() {
setGeometry(avail);
}
int32 navSkip = 2 * st::mvControlMargin + st::mvControlSize;
_closeNav = myrtlrect(width() - st::mvControlMargin - st::mvControlSize, st::mvControlMargin, st::mvControlSize, st::mvControlSize);
int32 navSkip = 2 * st::mediaviewControlMargin + st::mediaviewControlSize;
_closeNav = myrtlrect(width() - st::mediaviewControlMargin - st::mediaviewControlSize, st::mediaviewControlMargin, st::mediaviewControlSize, st::mediaviewControlSize);
_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);
_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);
_saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2);
@ -194,6 +196,10 @@ bool MediaView::fileShown() const {
return !_current.isNull() || gifShown();
}
bool MediaView::fileBubbleShown() const {
return _doc && !fileShown() && !_themePreviewShown;
}
bool MediaView::gifShown() const {
if (_gif && _gif->ready()) {
if (!_gif->started()) {
@ -220,7 +226,7 @@ void MediaView::stopGif() {
}
void MediaView::documentUpdated(DocumentData *doc) {
if (_doc && _doc == doc && !fileShown()) {
if (fileBubbleShown() && _doc == doc) {
if ((_doc->loading() && _docCancel->isHidden()) || (!_doc->loading() && !_docCancel->isHidden())) {
updateControls();
} else if (_doc->loading()) {
@ -238,7 +244,7 @@ void MediaView::changingMsgId(HistoryItem *row, MsgId newId) {
}
void MediaView::updateDocSize() {
if (!_doc || fileShown()) return;
if (!fileBubbleShown()) return;
if (_doc->loading()) {
quint64 ready = _doc->loadOffset(), total = _doc->size;
@ -262,16 +268,16 @@ void MediaView::updateDocSize() {
} else {
_docSize = formatSizeText(_doc->size);
}
_docSizeWidth = st::mvFont->width(_docSize);
_docSizeWidth = st::mediaviewFont->width(_docSize);
int32 maxw = st::mediaviewFileSize.width() - st::mediaviewFileIconSize - st::mediaviewFilePadding * 3;
if (_docSizeWidth > maxw) {
_docSize = st::mvFont->elided(_docSize, maxw);
_docSizeWidth = st::mvFont->width(_docSize);
_docSize = st::mediaviewFont->elided(_docSize, maxw);
_docSizeWidth = st::mediaviewFont->width(_docSize);
}
}
void MediaView::updateControls() {
if (_doc && !fileShown()) {
if (fileBubbleShown()) {
if (_doc->loading()) {
_docDownload->hide();
_docSaveAs->hide();
@ -299,10 +305,12 @@ void MediaView::updateControls() {
}
radialStart();
updateThemePreviewGeometry();
_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);
_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);
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()));
}
if (_from) {
_fromName.setText(st::mvFont, (_from->migrateTo() ? _from->migrateTo() : _from)->name, _textNameOptions);
_nameNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height);
_dateNav = myrtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height);
_fromName.setText(st::mediaviewTextStyle, (_from->migrateTo() ? _from->migrateTo() : _from)->name, _textNameOptions);
_nameNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mediaviewFont->height);
_dateNav = myrtlrect(st::mediaviewTextLeft + _nameNav.width() + st::mediaviewTextSkip, height() - st::mediaviewTextTop, st::mediaviewFont->width(_dateText), st::mediaviewFont->height);
} else {
_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();
if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewChatPhotos || _overview == OverviewFiles || _overview == OverviewVideos))) {
@ -354,9 +362,9 @@ void MediaView::updateControls() {
if (!_caption.isEmpty()) {
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 maxh = qMin(_caption.countHeight(maxw), int(height() / 4 - st::mvCaptionPadding.top() - st::mvCaptionPadding.bottom() - 2 * st::mvCaptionMargin.height()));
_captionRect = QRect((width() - maxw) / 2, height() - maxh - st::mvCaptionPadding.bottom() - st::mvCaptionMargin.height(), maxw, maxh);
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::mediaviewCaptionPadding.top() - st::mediaviewCaptionPadding.bottom() - 2 * st::mediaviewCaptionMargin.height()));
_captionRect = QRect((width() - maxw) / 2, height() - maxh - st::mediaviewCaptionPadding.bottom() - st::mediaviewCaptionMargin.height(), maxw, maxh);
} else {
_captionRect = QRect();
}
@ -410,7 +418,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
case OverMore: update(_moreNav); break;
default: break;
}
float64 dt = float64(ms - start) / st::mvFadeDuration;
float64 dt = float64(ms - start) / st::mediaviewFadeDuration;
if (dt >= 1) {
_animOpacities.remove(i.key());
i = _animations.erase(i);
@ -420,7 +428,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
}
}
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) {
a_cOpacity.finish();
_controlsState = (_controlsState == ControlsShowing ? ControlsShown : ControlsHidden);
@ -428,7 +436,7 @@ void MediaView::step_state(TimeMs ms, bool timer) {
} else {
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);
if (dt < 1) result = true;
}
@ -500,7 +508,7 @@ void MediaView::step_radial(TimeMs ms, bool timer) {
} else {
const FileLocation &location(_doc->location(true));
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));
}
location.accessDisable();
@ -626,7 +634,7 @@ void MediaView::close() {
void MediaView::activateControls() {
if (!_menu && !_mousePressed) {
_controlsHideTimer.start(int(st::mvWaitHide));
_controlsHideTimer.start(int(st::mediaviewWaitHide));
}
if (_fullScreenVideo) {
if (_clipController) {
@ -1120,6 +1128,7 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
stopGif();
destroyThemePreview();
_doc = nullptr;
_fullScreenVideo = false;
_photo = photo;
@ -1132,7 +1141,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
_caption = Text();
if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : nullptr) {
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();
}
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
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;
_current = QPixmap();
stopGif();
} else if (gifShown()) {
_current = QPixmap();
}
if (documentChanged || !doc->isTheme()) {
destroyThemePreview();
}
_doc = doc;
_photo = nullptr;
_radial.stop();
@ -1196,6 +1216,8 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (_doc->isAnimation() || _doc->isVideo()) {
initAnimation();
} else if (_doc->isTheme()) {
initThemePreview();
} else {
const FileLocation &location(_doc->location(true));
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);
if (!fileShown()) {
if (fileBubbleShown()) {
if (!_doc || _doc->thumb->isNull()) {
int32 colorIndex = documentColorIndex(_doc, _docExt);
_docIconColor = &documentColor(colorIndex);
_docIconColor = documentColor(colorIndex);
const style::icon *(thumbs[]) = { &st::mediaviewFileBlue, &st::mediaviewFileGreen, &st::mediaviewFileRed, &st::mediaviewFileYellow };
_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());
_docIconRect = myrtlrect(_docRect.x() + st::mediaviewFilePadding, _docRect.y() + st::mediaviewFilePadding, st::mediaviewFileIconSize, st::mediaviewFileIconSize);
} else if (_themePreviewShown) {
updateThemePreviewGeometry();
} else if (!_current.isNull()) {
_current.setDevicePixelRatio(cRetinaFactor());
_w = convertScale(_current.width());
@ -1304,6 +1328,25 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
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() {
updateControls();
if (isHidden()) {
@ -1363,6 +1406,59 @@ void MediaView::createClipReader() {
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() {
if (!_doc->isVideo()) return;
@ -1389,7 +1485,7 @@ void MediaView::setClipControllerGeometry() {
int controllerBottom = _captionRect.isEmpty() ? height() : _captionRect.y();
_clipController->setGeometry(
(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.height());
myEnsureResized(_clipController);
@ -1603,26 +1699,26 @@ void MediaView::paintEvent(QPaintEvent *e) {
if (_saveMsgStarted) {
auto ms = getms();
float64 dt = float64(ms) - _saveMsgStarted, hidingDt = dt - st::medviewSaveMsgShowing - st::medviewSaveMsgShown;
if (dt < st::medviewSaveMsgShowing + st::medviewSaveMsgShown + st::medviewSaveMsgHiding) {
float64 dt = float64(ms) - _saveMsgStarted, hidingDt = dt - st::mediaviewSaveMsgShowing - st::mediaviewSaveMsgShown;
if (dt < st::mediaviewSaveMsgShowing + st::mediaviewSaveMsgShown + st::mediaviewSaveMsgHiding) {
if (hidingDt >= 0 && _saveMsgOpacity.to() > 0.5) {
_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);
if (_saveMsgOpacity.current() > 0) {
p.setOpacity(_saveMsgOpacity.current());
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);
textstyleSet(&st::mediaviewTextStyle);
_saveMsgText.draw(p, _saveMsg.x() + st::medviewSaveMsgPadding.left(), _saveMsg.y() + st::medviewSaveMsgPadding.top(), _saveMsg.width() - st::medviewSaveMsgPadding.left() - st::medviewSaveMsgPadding.right());
textstyleRestore();
p.setTextPalette(st::mediaviewTextPalette);
_saveMsgText.draw(p, _saveMsg.x() + st::mediaviewSaveMsgPadding.left(), _saveMsg.y() + st::mediaviewSaveMsgPadding.top(), _saveMsg.width() - st::mediaviewSaveMsgPadding.left() - st::mediaviewSaveMsgPadding.right());
p.restoreTextPalette();
p.setOpacity(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);
}
} else {
@ -1630,6 +1726,8 @@ void MediaView::paintEvent(QPaintEvent *e) {
}
}
}
} else if (_themePreviewShown) {
paintThemePreview(p, r);
} else {
if (_docRect.intersects(r)) {
p.fillRect(_docRect, st::mediaviewFileBg);
@ -1642,7 +1740,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
radialOpacity = _radial.opacity();
}
if (!_doc || _doc->thumb->isNull()) {
p.fillRect(_docIconRect, (*_docIconColor)->b);
p.fillRect(_docIconRect, _docIconColor);
if ((!_doc || _doc->loaded()) && (!radial || radialOpacity < 1) && _docIcon) {
_docIcon->paint(p, _docIconRect.x() + (_docIconRect.width() - _docIcon->width()), _docIconRect.y(), width());
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.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);
}
}
@ -1685,7 +1783,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
}
}
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);
}
}
@ -1701,7 +1799,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
}
}
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);
}
}
@ -1717,7 +1815,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
}
}
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);
}
}
@ -1725,71 +1823,71 @@ void MediaView::paintEvent(QPaintEvent *e) {
// save button
if (_saveVisible && _saveNavIcon.intersects(r)) {
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);
}
// more area
if (_moreNavIcon.intersects(r)) {
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);
}
p.setPen(st::mediaviewControlFg);
p.setFont(st::mvThickFont);
p.setFont(st::mediaviewThickFont);
// header
if (_headerNav.intersects(r)) {
auto o = _headerHasLink ? overLevel(OverHeader) : 0;
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co);
p.drawText(_headerNav.left(), _headerNav.top() + st::mvThickFont->ascent, _headerText);
p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
p.drawText(_headerNav.left(), _headerNav.top() + st::mediaviewThickFont->ascent, _headerText);
if (o > 0) {
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
if (_from && _nameNav.intersects(r)) {
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());
if (o > 0) {
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
if (_dateNav.intersects(r)) {
float64 o = overLevel(OverDate);
p.setOpacity((o * st::mvIconOverOpacity + (1 - o) * st::mvIconOpacity) * co);
p.drawText(_dateNav.left(), _dateNav.top() + st::mvFont->ascent, _dateText);
p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
p.drawText(_dateNav.left(), _dateNav.top() + st::mediaviewFont->ascent, _dateText);
if (o > 0) {
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
if (!_caption.isEmpty()) {
QRect outer(_captionRect.marginsAdded(st::mvCaptionPadding));
QRect outer(_captionRect.marginsAdded(st::mediaviewCaptionPadding));
if (outer.intersects(r)) {
p.setOpacity(co);
p.setBrush(st::mediaviewCaptionBg);
p.setPen(Qt::NoPen);
p.drawRoundedRect(outer, st::mvCaptionRadius, st::mvCaptionRadius);
p.drawRoundedRect(outer, st::mediaviewCaptionRadius, st::mediaviewCaptionRadius);
if (_captionRect.intersects(r)) {
textstyleSet(&st::mediaviewTextStyle);
p.setTextPalette(st::mediaviewTextPalette);
p.setPen(st::mediaviewCaptionFg);
_caption.drawElided(p, _captionRect.x(), _captionRect.y(), _captionRect.width(), _captionRect.height() / st::mvCaptionFont->height);
textstyleRestore();
_caption.drawElided(p, _captionRect.x(), _captionRect.y(), _captionRect.width(), _captionRect.height() / st::mediaviewCaptionStyle.font->height);
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) {
if (_clipController) {
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))) {
onCopy();
} 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();
} else if (_doc && _doc->isVideo()) {
onVideoPauseResume();
@ -1957,8 +2098,8 @@ bool MediaView::moveToNext(int32 delta) {
_channel = _history ? _history->channelId() : NoChannel;
_canForward = _msgid > 0;
_canDelete = lastChatPhoto.item->canDelete();
stopGif();
displayPhoto(lastChatPhoto.photo, lastChatPhoto.item); preloadData(delta);
displayPhoto(lastChatPhoto.photo, lastChatPhoto.item);
preloadData(delta);
return true;
} else if (_history && (_history->overviewCount(OverviewChatPhotos) != 0 || (
_migrated && _migrated->overviewCount(OverviewChatPhotos) != 0))) {
@ -1994,7 +2135,7 @@ bool MediaView::moveToNext(int32 delta) {
_canForward = _msgid > 0;
_canDelete = item->canDelete();
stopGif();
if (HistoryMedia *media = item->getMedia()) {
if (auto media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
case MediaTypeFile:
@ -2013,7 +2154,6 @@ bool MediaView::moveToNext(int32 delta) {
_msgmigrated = false;
_canForward = false;
_canDelete = false;
stopGif();
displayPhoto(_additionalChatPhoto, 0);
}
if (delta < 0 && _index < MediaOverviewStartPerPage) {
@ -2189,8 +2329,8 @@ void MediaView::snapXY() {
void MediaView::mouseMoveEvent(QMouseEvent *e) {
updateOver(e->pos());
if (_lastAction.x() >= 0 && (e->pos() - _lastAction).manhattanLength() >= st::mvDeltaFromLastAction) {
_lastAction = QPoint(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction);
if (_lastAction.x() >= 0 && (e->pos() - _lastAction).manhattanLength() >= st::mediaviewDeltaFromLastAction) {
_lastAction = QPoint(-st::mediaviewDeltaFromLastAction, -st::mediaviewDeltaFromLastAction);
}
if (_pressed) {
if (!_dragging && (e->pos() - _mStart).manhattanLength() >= QApplication::startDragDistance()) {
@ -2267,7 +2407,7 @@ void MediaView::updateOver(QPoint pos) {
ClickHandlerHost *lnkhost = nullptr;
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;
lnkhost = this;
} else if (_captionRect.contains(pos)) {
@ -2302,7 +2442,7 @@ void MediaView::updateOver(QPoint pos) {
updateOverState(OverHeader);
} else if (_saveVisible && _saveNav.contains(pos)) {
updateOverState(OverSave);
} else if (_doc && !fileShown() && _docIconRect.contains(pos)) {
} else if (_doc && fileBubbleShown() && _docIconRect.contains(pos)) {
updateOverState(OverIcon);
} else if (_moreNav.contains(pos)) {
updateOverState(OverMore);
@ -2358,8 +2498,14 @@ void MediaView::mouseReleaseEvent(QMouseEvent *e) {
}
_dragging = 0;
setCursor(style::cur_default);
} else if ((e->pos() - _lastAction).manhattanLength() >= st::mvDeltaFromLastAction && (!_doc || fileShown() || !_docRect.contains(e->pos()))) {
close();
} else if ((e->pos() - _lastAction).manhattanLength() >= st::mediaviewDeltaFromLastAction) {
if (_themePreviewShown) {
if (!_themePreviewRect.contains(e->pos())) {
close();
}
} else if (!_doc || fileShown() || !_docRect.contains(e->pos())) {
close();
}
}
_pressed = false;
}
@ -2422,7 +2568,7 @@ void MediaView::touchEvent(QTouchEvent *e) {
} else if (_touchMove) {
if ((!_leftNavVisible || !_leftNav.contains(mapFromGlobal(_touchStart))) && (!_rightNavVisible || !_rightNav.contains(mapFromGlobal(_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);
}
}
@ -2500,6 +2646,7 @@ void MediaView::setVisible(bool visible) {
Sandbox::removeEventFilter(this);
stopGif();
destroyThemePreview();
_radial.stop();
Notify::clipStopperHidden(ClipStopperMediaview);
}
@ -2746,12 +2893,12 @@ void MediaView::updateHeader() {
}
}
_headerHasLink = _history && typeHasMediaOverview(_overview);
int32 hwidth = st::mvThickFont->width(_headerText);
int32 hwidth = st::mediaviewThickFont->width(_headerText);
if (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 {

View file

@ -32,8 +32,15 @@ class Controller;
namespace Ui {
class PopupMenu;
class LinkButton;
class RoundButton;
} // namespace Ui
namespace Window {
namespace Theme {
struct Preview;
} // namespace Theme
} // namespace Window
struct AudioPlaybackState;
class MediaView : public TWidget, private base::Subscriber, public RPCSender, public ClickHandlerHost {
@ -127,6 +134,20 @@ private slots:
void onVideoPlayProgress(const AudioMsgId &audioId);
private:
enum OverState {
OverNone,
OverLeftNav,
OverRightNav,
OverClose,
OverHeader,
OverName,
OverDate,
OverSave,
OverMore,
OverIcon,
OverVideo,
};
void showSaveMsgFile();
void dropdownHidden();
@ -155,6 +176,10 @@ private:
void initAnimation();
void createClipReader();
void initThemePreview();
void destroyThemePreview();
void updateThemePreviewGeometry();
// Radial animation interface.
float64 radialProgress() const;
bool radialLoading() const;
@ -187,6 +212,11 @@ private:
void zoomUpdate(int32 &newZoom);
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;
@ -236,10 +266,11 @@ private:
bool fileShown() const;
bool gifShown() const;
bool fileBubbleShown() const;
void stopGif();
const style::icon *_docIcon = nullptr;
const style::color *_docIconColor = nullptr;
style::color _docIconColor;
QString _docName, _docSize, _docExt;
int _docNameWidth = 0, _docSizeWidth = 0, _docExtWidth = 0;
QRect _docRect, _docIconRect;
@ -278,19 +309,6 @@ private:
mtpRequestId _loadRequest = 0;
enum OverState {
OverNone,
OverLeftNav,
OverRightNav,
OverClose,
OverHeader,
OverName,
OverDate,
OverSave,
OverMore,
OverIcon,
OverVideo,
};
OverState _over = OverNone;
OverState _down = OverNone;
QPoint _lastAction, _lastMouseMovePos;
@ -340,8 +358,11 @@ private:
int _verticalWheelDelta = 0;
void updateOverRect(OverState state);
bool updateOverState(OverState newState);
float64 overLevel(OverState control) const;
bool _themePreviewShown = false;
uint64 _themePreviewId = 0;
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();
QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date))));
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));
}
@ -578,9 +578,9 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
p.setPen(selected ? st::mediaInFgSelected : st::mediaInFg);
int32 unreadx = nameleft;
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);
textstyleRestore();
p.restoreTextPalette();
unreadx += _details.maxWidth();
} else {
int32 statusw = st::normalFont->width(_status.text());
@ -631,12 +631,12 @@ void Voice::updateName() {
int32 version = 0;
if (const HistoryMessageForwarded *fwd = _parent->Get<HistoryMessageForwarded>()) {
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 {
_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 {
_name.setText(st::semiboldFont, App::peerName(_parent->from()), _textNameOptions);
_name.setText(st::semiboldTextStyle, App::peerName(_parent->from()), _textNameOptions);
}
version = _parent->fromOriginal()->nameVersion;
_nameVersion = version;
@ -675,7 +675,7 @@ Document::Document(DocumentData *document, HistoryItem *parent, const style::Ove
, _date(langDateTime(date(_data->date)))
, _datew(st::normalFont->width(_date))
, _colorIndex(documentColorIndex(_data, _ext)) {
_name.setMarkedText(st::normalFont, documentNameWithEntities(_data), _documentNameOptions);
_name.setMarkedText(st::defaultTextStyle, documentNameWithEntities(_data), _documentNameOptions);
AddComponents(Info::Bit());
@ -806,7 +806,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
}
}
if (selected) {
p.fillRect(rthumb, textstyleCurrent()->selectOverlay);
p.fillRect(rthumb, st::defaultTextPalette.selectOverlay);
}
if (radial || (!loaded && !_data->loading())) {
@ -1029,7 +1029,7 @@ Link::Link(HistoryMedia *media, HistoryItem *parent) : ItemBase(parent) {
}
if (till > from) {
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;
if (_page && _page->photo) {

View file

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

View file

@ -45,7 +45,7 @@ public:
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();
@ -71,7 +71,7 @@ protected:
void psTrayMenuUpdated();
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:
void updateIconCounters();

View file

@ -49,7 +49,7 @@ public:
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;
@ -99,7 +99,7 @@ protected:
void psTrayMenuUpdated();
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;

View file

@ -205,9 +205,8 @@ MainWindow::MainWindow()
, iconbig256(qsl(":/gui/art/iconbig256.png"))
, wndIcon(QPixmap::fromImage(iconbig256, Qt::ColorOnly))
, _private(std_::make_unique<Private>(this)) {
QImage tray(qsl(":/gui/art/osxtray.png"));
trayImg = tray.copy(0, cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4));
trayImgSel = tray.copy(tray.width() / (cRetina() ? 2 : 4), cRetina() ? 0 : tray.width() / 2, tray.width() / (cRetina() ? 2 : 4), tray.width() / (cRetina() ? 2 : 4));
trayImg = st::macTrayIcon.instance(QColor(0, 0, 0, 180), dbisOne);
trayImgSel = st::macTrayIcon.instance(QColor(255, 255, 255), dbisOne);
_hideAfterFullScreenTimer.setSingleShot(true);
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;
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'));
int32 cntSize = cnt.size();
{
Painter p(&img);
PainterHighQualityEnabler hq(p);
p.setBrush(bg->b);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::Antialiasing);
int32 fontSize, skip;
if (size == 22) {
skip = 1;
fontSize = 8;
} else {
skip = 2;
fontSize = 16;
auto cnt = (count < 100) ? QString("%1").arg(count) : QString("..%1").arg(count % 100, 2, 10, QChar('0'));
auto cntSize = cnt.size();
p.setBrush(bg);
p.setPen(Qt::NoPen);
int32 fontSize, skip;
if (size == 22) {
skip = 1;
fontSize = 8;
} 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);
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);
img.setDevicePixelRatio(savedRatio);
}
void MainWindow::updateTitleCounter() {

View file

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

View file

@ -21,10 +21,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h"
#include "platform/mac/window_title_mac.h"
#include "mainwindow.h"
#include "ui/widgets/shadow.h"
#include "styles/style_window.h"
#include "styles/style_mediaview.h"
#include "platform/platform_main_window.h"
#include <Cocoa/Cocoa.h>
#include <CoreFoundation/CFURL.h>
namespace Platform {
TitleWidget::TitleWidget(MainWindow *parent, int height) : Window::TitleWidget(parent)
@ -84,4 +89,138 @@ object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
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

View file

@ -22,6 +22,15 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#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
#include "platform/mac/window_title_mac.h"
#elif defined Q_OS_WIN // Q_OS_MAC
@ -34,6 +43,14 @@ inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
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
#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 "localstorage.h"
#include "ui/widgets/popup_menu.h"
#include "window/window_theme.h"
#include <qpa/qplatformnativeinterface.h>
@ -143,11 +144,11 @@ public:
bool init(QColor c) {
_fullsize = st::windowShadow.width();
_shift = st::windowShadowShift;
QImage cornersImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied);
auto cornersImage = QImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied);
{
Painter p(&cornersImage);
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);
@ -529,7 +530,6 @@ private:
};
_PsShadowWindows _psShadowWindows;
QColor _shActive(0, 0, 0)/*, _shInactive(0, 0, 0)*/;
LRESULT CALLBACK _PsShadowWindows::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
auto wnd = App::wnd();
@ -618,6 +618,12 @@ MainWindow::MainWindow()
if (!_taskbarCreatedMsgId) {
_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() {
@ -791,7 +797,7 @@ bool MainWindow::psHasNativeNotifications() {
Q_DECLARE_METATYPE(QMargins);
void MainWindow::psFirstShow() {
_psShadowWindows.init(_shActive);
_psShadowWindows.init(st::windowShadowFg->c);
_shadowsWorking = true;
psUpdateMargins();

View file

@ -52,7 +52,7 @@ public:
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() {
return _taskbarCreatedMsgId;
@ -104,7 +104,7 @@ protected:
void psTrayMenuUpdated();
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;

View file

@ -27,6 +27,15 @@ class IconButton;
class PlainShadow;
} // 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 {
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);
}
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

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
*/
using "basic.style";
using "basic_types.style";
using "ui/widgets/widgets.style";
using "window/window.style";
@ -38,12 +37,14 @@ profileNameLeft: 26px;
profileNameTop: 9px;
profileNameLabel: FlatLabel(defaultFlatLabel) {
margin: margins(10px, 5px, 10px, 5px);
font: font(16px semibold);
width: 160px;
maxHeight: 24px;
textFg: windowBoldFg;
}
profileNameTextStyle: TextStyle(defaultTextStyle) {
style: TextStyle(defaultTextStyle) {
font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
}
profileStatusLeft: 27px;
profileStatusTop: 35px;
@ -135,9 +136,9 @@ profileMemberAdminIcon: icon {{ "profile_admin_star", windowBgActive, point(4px,
profileLimitReachedLabel: FlatLabel(defaultFlatLabel) {
width: 180px;
margin: margins(profileMemberPaddingLeft, 9px, profileMemberPaddingLeft, 6px);
}
profileLimitReachedStyle: TextStyle(defaultTextStyle) {
lineHeight: 19px;
style: TextStyle(defaultTextStyle) {
lineHeight: 19px;
}
}
profileReportReasonOther: InputField(defaultInputField) {

View file

@ -209,7 +209,7 @@ void GroupMembersWidget::refreshLimitReached() {
bool limitReachedShown = (itemsCount() >= Global::ChatSizeMax()) && chat->amCreator() && !emptyTitle();
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 body = textRichPrepare(lang(lng_profile_migrate_body));
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());
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 nameTop = y + st::profileMemberNamePosition.y();

View file

@ -242,7 +242,7 @@ void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) {
y += st::profileCommonGroupsNameTop;
auto nameWidth = _contentWidth - (x - _contentLeft) - st::profileCommonGroupsPadding.right();
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());
}

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
*/
using "basic.style";
using "basic_types.style";
using "dialogs/dialogs.style";
using "ui/widgets/widgets.style";
using "boxes/boxes.style";
@ -50,12 +49,14 @@ settingsNameLeft: 26px;
settingsNameTop: 9px;
settingsNameLabel: FlatLabel(defaultFlatLabel) {
margin: margins(10px, 5px, 10px, 5px);
font: font(16px semibold);
width: 160px;
maxHeight: 24px;
textFg: windowBoldFg;
}
settingsNameTextStyle: TextStyle(defaultTextStyle) {
style: TextStyle(defaultTextStyle) {
font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
}
settingsStatusLeft: 27px;
settingsStatusTop: 35px;
@ -87,7 +88,11 @@ settingsBlockTitleFont: font(15px semibold);
settingsBlockTitleFg: windowBoldFg;
settingsBlockTitleTop: 0px;
settingsPrimaryLabel: FlatLabel(defaultFlatLabel) {
font: boxTextFont;
style: TextStyle(defaultTextStyle) {
font: boxTextFont;
linkFont: boxTextFont;
linkFontOver: font(boxFontSize underline);
}
}
settingsBlockLabel: FlatLabel(settingsPrimaryLabel) {
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 "styles/palette.h"
#include "styles/style_basic_types.h"
#include "styles/style_basic.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 "localstorage.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "ui/toast/toast.h"
#include "styles/style_stickers.h"
namespace Stickers {
namespace {
@ -78,16 +81,19 @@ void applyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
}
Local::writeInstalledStickers();
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();
}
// For testing: Just apply random subset or your sticker sets as archived.
bool applyArchivedResultFake() {
if (rand_value<uint32>() % 128 < 64) {
return false;
}
auto sets = QVector<MTPStickerSetCovered>();
for (auto &set : Global::RefStickerSets()) {
if ((set.flags & MTPDstickerSet::Flag::f_installed) && !(set.flags & MTPDstickerSet_ClientFlag::f_special)) {

View file

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

View file

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

View file

@ -203,7 +203,7 @@ static constexpr int kUserColorsCount = 8;
static constexpr int kChatColorsCount = 4;
static constexpr int kChannelColorsCount = 4;
const style::color &peerColor(int index);
style::color peerColor(int index);
ImagePtr userDefPhoto(int index);
ImagePtr chatDefPhoto(int index);
ImagePtr channelDefPhoto(int index);
@ -289,7 +289,7 @@ public:
MTPinputPeer input;
int colorIndex;
const style::color &color;
style::color color;
void setUserpic(ImagePtr userpic);
void paintUserpic(Painter &p, int size, int x, int y) const;
@ -1136,6 +1136,9 @@ public:
bool isGifv() const {
return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive);
}
bool isTheme() const {
return name.endsWith(qstr(".tdesktop-theme"), Qt::CaseInsensitive);
}
bool isMusic() const {
if (auto s = song()) {
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
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);
}
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);
}
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);
}
@ -353,15 +353,15 @@ FORCE_INLINE QPen pen(QColor a, QColor b, float64 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;
}
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;
}
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;
}
@ -369,15 +369,15 @@ FORCE_INLINE QBrush brush(QColor a, QColor b, float64 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;
}
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;
}
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;
}

View file

@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
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);
auto deleteScale = shown + st.minScale * (1. - shown);

View file

@ -26,7 +26,7 @@ namespace Ui {
class CrossAnimation {
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);
}
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();
p.setOpacity(o * _opacity);

View file

@ -42,7 +42,7 @@ public:
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:
TimeMs _firstStart = 0;

View file

@ -51,13 +51,13 @@ public:
}
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 };
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);
p.setPen(Qt::NoPen);
p.setBrush(color);
@ -96,13 +96,13 @@ public:
}
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 };
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);
auto pen = color->p;
pen.setWidth(st::historySendActionRecordStrokeNumerator / st::historySendActionRecordDenominator);
@ -140,13 +140,13 @@ public:
}
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 };
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);
auto pen = color->p;
pen.setWidth(st::historySendActionUploadStrokeNumerator / st::historySendActionUploadDenominator);

View file

@ -32,7 +32,7 @@ public:
int width() const {
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) {
_impl->paint(p, color, x, y, outerWidth, ms);
}
@ -57,14 +57,14 @@ public:
bool supports(Type type) const;
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);
}
virtual ~Impl() = default;
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;
TimeMs _started = 0;

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