mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-20 22:41:11 +00:00
Ripple animations done for IconButton, FlatButton and RoundButton.
Also moved input field classes to ui/widgets/input_fields module.
This commit is contained in:
parent
48eb72a9c2
commit
3186e1e495
@ -57,156 +57,12 @@ boxTitlePosition: point(26px, 28px);
|
||||
boxTitleHeight: 54px;
|
||||
|
||||
boxButtonFont: font(boxFontSize semibold);
|
||||
defaultBoxButton: RoundButton {
|
||||
textFg: #2f9fea;
|
||||
textFgOver: #2f9fea;
|
||||
secondaryTextFg: #2f9fea;
|
||||
secondaryTextFgOver: #2f9fea;
|
||||
textBg: boxBg;
|
||||
textBgOver: lightButtonBgOver;
|
||||
|
||||
width: -24px;
|
||||
height: 36px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
downTextTop: 9px;
|
||||
|
||||
font: boxButtonFont;
|
||||
}
|
||||
cancelBoxButton: RoundButton(defaultBoxButton) {
|
||||
textFg: #aeaeae;
|
||||
}
|
||||
attentionBoxButton: RoundButton(defaultBoxButton) {
|
||||
textFg: #ea4b2f;
|
||||
textFgOver: #ea4b2f;
|
||||
textBgOver: #fff0ed;
|
||||
}
|
||||
boxButtonPadding: margins(12px, 16px, 22px, 16px);
|
||||
boxLabel: flatLabel(labelDefFlat) {
|
||||
font: font(boxFontSize);
|
||||
align: align(topleft);
|
||||
}
|
||||
|
||||
defaultLeftOutlineButton: OutlineButton {
|
||||
outlineWidth: 3px;
|
||||
outlineFg: windowBg;
|
||||
outlineFgOver: windowActiveBg;
|
||||
|
||||
textBg: windowBg;
|
||||
textBgOver: #f2f7fa;
|
||||
|
||||
textFg: windowActiveTextFg;
|
||||
textFgOver: windowActiveTextFg;
|
||||
|
||||
font: normalFont;
|
||||
padding: margins(11px, 5px, 11px, 5px);
|
||||
}
|
||||
attentionLeftOutlineButton: OutlineButton(defaultLeftOutlineButton) {
|
||||
outlineFgOver: #e43f3f;
|
||||
|
||||
textBgOver: #faf2f2;
|
||||
|
||||
textFg: #d15948;
|
||||
textFgOver: #d15948;
|
||||
}
|
||||
|
||||
defaultInputArea: InputArea {
|
||||
textBg: windowBg;
|
||||
textFg: windowTextFg;
|
||||
textMargins: margins(5px, 6px, 5px, 4px);
|
||||
|
||||
placeholderFg: #999999;
|
||||
placeholderFgActive: #aaaaaa;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
placeholderAlign: align(topleft);
|
||||
placeholderShift: 50px;
|
||||
duration: 120;
|
||||
|
||||
borderFg: #e0e0e0;
|
||||
borderFgActive: #62c0f7;
|
||||
borderFgError: #e48383;
|
||||
|
||||
border: 1px;
|
||||
borderActive: 2px;
|
||||
borderError: 2px;
|
||||
|
||||
font: boxTextFont;
|
||||
|
||||
heightMin: 32px;
|
||||
heightMax: 128px;
|
||||
}
|
||||
defaultInputField: InputField {
|
||||
textBg: windowBg;
|
||||
textFg: windowTextFg;
|
||||
textMargins: margins(0px, 6px, 0px, 4px);
|
||||
textAlign: align(topleft);
|
||||
|
||||
placeholderFg: #999999;
|
||||
placeholderFgActive: #aaaaaa;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
placeholderAlign: align(topleft);
|
||||
placeholderShift: 50px;
|
||||
duration: 120;
|
||||
|
||||
borderFg: #e0e0e0;
|
||||
borderFgActive: #62c0f7;
|
||||
borderFgError: #e48383;
|
||||
|
||||
border: 1px;
|
||||
borderActive: 2px;
|
||||
borderError: 2px;
|
||||
|
||||
font: boxTextFont;
|
||||
|
||||
height: 32px;
|
||||
}
|
||||
defaultCheckboxIcon: icon {{ "default_checkbox_check", windowActiveFg, point(4px, 7px) }};
|
||||
defaultCheckbox: Checkbox {
|
||||
textFg: windowTextFg;
|
||||
textBg: windowBg;
|
||||
|
||||
checkBg: #ffffff;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #b3b3b3;
|
||||
checkFgActive: windowActiveBg;
|
||||
|
||||
width: -44px;
|
||||
height: 22px;
|
||||
|
||||
textPosition: point(32px, 2px);
|
||||
diameter: 22px;
|
||||
thickness: 2px;
|
||||
checkIcon: defaultCheckboxIcon;
|
||||
|
||||
font: normalFont;
|
||||
duration: 120;
|
||||
}
|
||||
defaultBoxCheckbox: Checkbox(defaultCheckbox) {
|
||||
width: -46px;
|
||||
textPosition: point(34px, 1px);
|
||||
font: boxTextFont;
|
||||
}
|
||||
defaultRadiobutton: Radiobutton {
|
||||
textFg: windowTextFg;
|
||||
textBg: windowBg;
|
||||
|
||||
checkBg: #ffffff;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #bfbfbf;
|
||||
checkFgActive: #4eb3ee;
|
||||
|
||||
width: -46px;
|
||||
height: 22px;
|
||||
|
||||
textPosition: point(34px, 0px);
|
||||
diameter: 22px;
|
||||
thickness: 2px;
|
||||
checkSkip: 65px; // * 0.1
|
||||
|
||||
font: boxTextFont;
|
||||
duration: 120;
|
||||
}
|
||||
solidScroll: flatScroll {
|
||||
barColor: #3f729734;
|
||||
bgColor: #214f751a;
|
||||
@ -279,40 +135,6 @@ linkCropLimit: 360px;
|
||||
linkFont: normalFont;
|
||||
linkOverFont: font(fsize underline);
|
||||
|
||||
inpDefFont: font(17px);
|
||||
inpDefFlat: flatInput {
|
||||
textColor: #000000;
|
||||
bgColor: #ffffff;
|
||||
bgActive: #ffffff;
|
||||
width: 210px;
|
||||
height: 40px;
|
||||
align: align(left);
|
||||
textMrg: margins(5px, 5px, 5px, 5px);
|
||||
font: inpDefFont;
|
||||
cursor: cursor(text);
|
||||
|
||||
borderWidth: 0px;
|
||||
borderColor: transparent;
|
||||
borderActive: transparent;
|
||||
borderError: transparent;
|
||||
|
||||
phColor: #949494;
|
||||
phFocusColor: #aaaaaa;
|
||||
phAlign: align(left);
|
||||
phPos: point(2px, 0px);
|
||||
phShift: 50px;
|
||||
phDuration: 100;
|
||||
}
|
||||
|
||||
inpDefGray: flatInput(inpDefFlat) {
|
||||
bgColor: #f2f2f2;
|
||||
borderWidth: 2px;
|
||||
borderColor: #f2f2f2;
|
||||
borderActive: #54c3f3;
|
||||
borderError: #ed8080;
|
||||
phColor: #808080;
|
||||
}
|
||||
|
||||
scrollDef: flatScroll {
|
||||
barColor: #00000053;
|
||||
bgColor: #0000001a;
|
||||
@ -375,63 +197,6 @@ noContactsHeight: 100px;
|
||||
noContactsFont: font(fsize);
|
||||
noContactsColor: #777777;
|
||||
|
||||
topBarHeight: 54px;
|
||||
topBarDuration: 200;
|
||||
topBarBackward: icon {{ "title_back", #a3a3a3 }};
|
||||
topBarForwardAlpha: 0.6;
|
||||
topBarBack: icon {{ "title_back", #259fd8 }};
|
||||
topBarBackAlpha: 0.8;
|
||||
topBarBackColor: #005faf;
|
||||
topBarBackFont: font(16px);
|
||||
topBarArrowPadding: margins(39px, 8px, 17px, 8px);
|
||||
topBarMinPadding: 5px;
|
||||
topBarButton: RoundButton {
|
||||
textFg: btnYesColor;
|
||||
textFgOver: btnYesColor;
|
||||
secondaryTextFg: btnYesColor;
|
||||
secondaryTextFgOver: btnYesColor;
|
||||
textBg: windowBg;
|
||||
textBgOver: #edf4f7;
|
||||
|
||||
width: -22px;
|
||||
height: 28px;
|
||||
padding: margins(0px, 14px, 12px, 12px);
|
||||
|
||||
textTop: 6px;
|
||||
downTextTop: 7px;
|
||||
|
||||
font: font(fsize);
|
||||
}
|
||||
defaultActiveButton: RoundButton {
|
||||
textFg: activeButtonFg;
|
||||
textFgOver: activeButtonFgOver;
|
||||
secondaryTextFg: activeButtonSecondaryFg;
|
||||
secondaryTextFgOver: activeButtonSecondaryFgOver;
|
||||
textBg: activeButtonBg;
|
||||
textBgOver: activeButtonBgOver;
|
||||
|
||||
secondarySkip: 7px;
|
||||
|
||||
width: -34px;
|
||||
height: 34px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
downTextTop: 9px;
|
||||
|
||||
font: semiboldFont;
|
||||
}
|
||||
defaultLightButton: RoundButton(defaultActiveButton) {
|
||||
textFg: lightButtonFg;
|
||||
textFgOver: lightButtonFgOver;
|
||||
textBg: lightButtonBg;
|
||||
textBgOver: lightButtonBgOver;
|
||||
}
|
||||
topBarClearButton: RoundButton(defaultLightButton) {
|
||||
width: -18px;
|
||||
}
|
||||
topBarActionSkip: 10px;
|
||||
|
||||
activeFadeInDuration: 500;
|
||||
activeFadeOutDuration: 3000;
|
||||
|
||||
@ -704,13 +469,6 @@ boxPhotoTextFg: #808080;
|
||||
cropPointSize: 10px;
|
||||
cropSkip: 13px;
|
||||
cropMinSize: 20px;
|
||||
confirmCaptionArea: InputArea(defaultInputArea) {
|
||||
textMargins: margins(1px, 6px, 1px, 4px);
|
||||
heightMax: 56px;
|
||||
}
|
||||
confirmBg: #f2f2f2;
|
||||
confirmMaxHeight: 245px;
|
||||
confirmCompressedSkip: 10px;
|
||||
|
||||
profileMaxWidth: 410px;
|
||||
profilePadding: margins(28px, 30px, 28px, 0px);
|
||||
@ -725,20 +483,6 @@ forwardFont: font(16px);
|
||||
forwardBg: #0000004c;
|
||||
forwardFg: #ffffff;
|
||||
|
||||
connectionHostInputField: InputField(defaultInputField) {
|
||||
width: 160px;
|
||||
}
|
||||
connectionPortInputField: InputField(defaultInputField) {
|
||||
width: 55px;
|
||||
}
|
||||
connectionUserInputField: InputField(defaultInputField) {
|
||||
width: 95px;
|
||||
}
|
||||
connectionPasswordInputField: InputField(defaultInputField) {
|
||||
width: 120px;
|
||||
}
|
||||
connectionIPv6Skip: 11px;
|
||||
|
||||
emojiTextFont: font(15px);
|
||||
emojiReplaceWidth: 52px;
|
||||
emojiReplaceHeight: 56px;
|
||||
@ -784,12 +528,6 @@ botKbScroll: flatScroll(solidScroll) {
|
||||
deltax: 3px;
|
||||
width: 10px;
|
||||
}
|
||||
switchPmButton: RoundButton(defaultBoxButton) {
|
||||
width: 320px;
|
||||
height: 34px;
|
||||
textTop: 7px;
|
||||
downTextTop: 8px;
|
||||
}
|
||||
|
||||
minPhotoSize: 100px;
|
||||
maxMediaSize: 420px;
|
||||
@ -867,23 +605,6 @@ videoIcon: icon {
|
||||
};
|
||||
locationSize: size(320px, 240px);
|
||||
|
||||
boxOptionListPadding: margins(2px, 20px, 2px, 2px);
|
||||
|
||||
langsWidth: 256px;
|
||||
langsButton: Radiobutton(defaultRadiobutton) {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
backgroundPadding: 10px;
|
||||
backgroundSize: size(108px, 193px);
|
||||
backgroundScroll: flatScroll(boxScroll) {
|
||||
round: 2px;
|
||||
width: 10px;
|
||||
deltax: 3px;
|
||||
deltat: 10px;
|
||||
deltab: 0px;
|
||||
}
|
||||
|
||||
mentionHeight: 40px;
|
||||
mentionScroll: flatScroll(scrollDef) {
|
||||
topsh: 0px;
|
||||
@ -934,11 +655,6 @@ inlineRowFileDescriptionTop: 23px;
|
||||
inlineResultsMinWidth: 64px;
|
||||
inlineDurationMargin: 3px;
|
||||
|
||||
editTextArea: InputArea(defaultInputArea) {
|
||||
textMargins: margins(1px, 6px, 1px, 4px);
|
||||
heightMax: 256px;
|
||||
}
|
||||
|
||||
toastFont: normalFont;
|
||||
toastMaxWidth: 480px;
|
||||
toastMinMargin: 13px;
|
||||
@ -948,11 +664,6 @@ toastPadding: margins(19px, 13px, 19px, 12px);
|
||||
toastFadeInDuration: 200;
|
||||
toastFadeOutDuration: 1000;
|
||||
|
||||
infoButton: PeerAvatarButton {
|
||||
size: topBarHeight;
|
||||
photoSize: 42px;
|
||||
}
|
||||
|
||||
// forward declaration for single "title_back" usage.
|
||||
profileTopBarBackIconFg: #0290d7;
|
||||
profileTopBarBackIcon: icon {{ "title_back", profileTopBarBackIconFg }};
|
||||
|
@ -30,49 +30,6 @@ textStyle {
|
||||
lineHeight: pixels;
|
||||
}
|
||||
|
||||
flatInput {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
bgActive: color;
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
icon: icon;
|
||||
|
||||
borderWidth: pixels;
|
||||
borderColor: color;
|
||||
borderActive: color;
|
||||
borderError: color;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: pixels;
|
||||
phDuration: int;
|
||||
}
|
||||
|
||||
flatTextarea {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
width: pixels;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: pixels;
|
||||
phDuration: int;
|
||||
}
|
||||
|
||||
flatScroll {
|
||||
barColor: color;
|
||||
bgColor: color;
|
||||
@ -125,143 +82,3 @@ botKeyboardButton {
|
||||
textTop: pixels;
|
||||
downTextTop: pixels;
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
textFg: color;
|
||||
textFgOver: color;
|
||||
textBg: color; // rect of textBg with rounded rect of textBgOver upon it
|
||||
textBgOver: color;
|
||||
|
||||
secondaryTextFg: color;
|
||||
secondaryTextFgOver: color;
|
||||
secondarySkip: pixels;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
padding: margins;
|
||||
|
||||
textTop: pixels;
|
||||
downTextTop: pixels;
|
||||
|
||||
icon: icon;
|
||||
|
||||
font: font;
|
||||
}
|
||||
|
||||
Checkbox {
|
||||
textFg: color;
|
||||
textBg: color;
|
||||
|
||||
checkBg: color;
|
||||
checkFg: color;
|
||||
checkFgOver: color;
|
||||
checkFgActive: color;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
|
||||
textPosition: point;
|
||||
diameter: pixels;
|
||||
thickness: pixels;
|
||||
checkIcon: icon;
|
||||
|
||||
font: font;
|
||||
duration: int;
|
||||
}
|
||||
|
||||
Radiobutton {
|
||||
textFg: color;
|
||||
textBg: color;
|
||||
|
||||
checkBg: color;
|
||||
checkFg: color;
|
||||
checkFgOver: color;
|
||||
checkFgActive: color;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
|
||||
textPosition: point;
|
||||
diameter: pixels;
|
||||
thickness: pixels;
|
||||
checkSkip: pixels;
|
||||
|
||||
font: font;
|
||||
duration: int;
|
||||
}
|
||||
|
||||
InputArea {
|
||||
textBg: color;
|
||||
textFg: color;
|
||||
textMargins: margins;
|
||||
|
||||
placeholderFg: color;
|
||||
placeholderFgActive: color;
|
||||
placeholderMargins: margins;
|
||||
placeholderAlign: align;
|
||||
placeholderShift: pixels;
|
||||
|
||||
duration: int;
|
||||
|
||||
borderFg: color;
|
||||
borderFgActive: color;
|
||||
borderFgError: color;
|
||||
|
||||
border: pixels;
|
||||
borderActive: pixels;
|
||||
borderError: pixels;
|
||||
|
||||
font: font;
|
||||
|
||||
width: pixels;
|
||||
heightMin: pixels;
|
||||
heightMax: pixels;
|
||||
}
|
||||
|
||||
InputField {
|
||||
textBg: color;
|
||||
textFg: color;
|
||||
textMargins: margins;
|
||||
textAlign: align;
|
||||
|
||||
placeholderFg: color;
|
||||
placeholderFgActive: color;
|
||||
placeholderMargins: margins;
|
||||
placeholderAlign: align;
|
||||
placeholderShift: pixels;
|
||||
|
||||
duration: int;
|
||||
|
||||
borderFg: color;
|
||||
borderFgActive: color;
|
||||
borderFgError: color;
|
||||
|
||||
border: pixels;
|
||||
borderActive: pixels;
|
||||
borderError: pixels;
|
||||
|
||||
font: font;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
}
|
||||
|
||||
PeerAvatarButton {
|
||||
size: pixels;
|
||||
photoSize: pixels;
|
||||
}
|
||||
|
||||
OutlineButton {
|
||||
outlineWidth: pixels;
|
||||
outlineFg: color;
|
||||
outlineFgOver: color;
|
||||
|
||||
textBg: color;
|
||||
textBgOver: color;
|
||||
|
||||
textFg: color;
|
||||
textFgOver: color;
|
||||
|
||||
font: font;
|
||||
padding: margins;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ imageBgTransparent: #ffffff;
|
||||
// widgets
|
||||
activeButtonBg: windowActiveBg;
|
||||
activeButtonBgOver: #46b4eb;
|
||||
activeButtonBgRipple: #177eb2;
|
||||
activeButtonFg: windowActiveFg;
|
||||
activeButtonFgOver: activeButtonFg;
|
||||
activeButtonSecondaryFg: #cceeff;
|
||||
@ -44,6 +45,7 @@ activeButtonSecondaryFgOver: activeButtonSecondaryFg;
|
||||
|
||||
lightButtonBg: windowBg;
|
||||
lightButtonBgOver: #edf7ff;
|
||||
lightButtonBgRipple: #c7e1f6;
|
||||
lightButtonFg: #2b99d5;
|
||||
lightButtonFgOver: lightButtonFg;
|
||||
|
||||
@ -92,6 +94,11 @@ boxBlockTitleAdditionalFg: #808080;
|
||||
boxBlockTitleCloseFg: cancelIconFg;
|
||||
boxBlockTitleCloseFgOver: cancelIconFgOver;
|
||||
|
||||
attentionBoxButtonFg: #ea4b2f;
|
||||
attentionBoxButtonFgOver: #ea4b2f;
|
||||
attentionBoxButtonBgOver: #fff0ed;
|
||||
attentionBoxButtonBgRipple: #efbcb2;
|
||||
|
||||
membersAboutLimitFg: windowSubTextFg;
|
||||
|
||||
contactsBg: windowBg;
|
||||
@ -188,6 +195,7 @@ historyReplyCancelFgOver: cancelIconFgOver;
|
||||
|
||||
historyComposeButtonBg: historyComposeAreaBg;
|
||||
historyComposeButtonBgOver: #f5f5f5;
|
||||
historyComposeButtonBgRipple: #e7e7e7;
|
||||
|
||||
historyTextInFg: windowTextFg;
|
||||
historyTextOutFg: windowTextFg;
|
||||
|
@ -35,12 +35,14 @@ imageBg: #000000;
|
||||
imageBgTransparent: #ffffff;
|
||||
activeButtonBg: windowActiveBg;
|
||||
activeButtonBgOver: #46b4eb;
|
||||
activeButtonBgRipple: #177eb2;
|
||||
activeButtonFg: windowActiveFg;
|
||||
activeButtonFgOver: activeButtonFg;
|
||||
activeButtonSecondaryFg: #cceeff;
|
||||
activeButtonSecondaryFgOver: activeButtonSecondaryFg;
|
||||
lightButtonBg: windowBg;
|
||||
lightButtonBgOver: #edf7ff;
|
||||
lightButtonBgRipple: #c7e1f6;
|
||||
lightButtonFg: #2b99d5;
|
||||
lightButtonFgOver: lightButtonFg;
|
||||
menuBg: windowBg;
|
||||
@ -77,6 +79,10 @@ boxBlockTitleFg: boxTitleFg;
|
||||
boxBlockTitleAdditionalFg: #808080;
|
||||
boxBlockTitleCloseFg: cancelIconFg;
|
||||
boxBlockTitleCloseFgOver: cancelIconFgOver;
|
||||
attentionBoxButtonFg: #ea4b2f;
|
||||
attentionBoxButtonFgOver: #ea4b2f;
|
||||
attentionBoxButtonBgOver: #fff0ed;
|
||||
attentionBoxButtonBgRipple: #efbcb2;
|
||||
membersAboutLimitFg: windowSubTextFg;
|
||||
contactsBg: windowBg;
|
||||
contactsBgOver: windowOverBg;
|
||||
@ -155,6 +161,7 @@ historyReplyCancelFg: cancelIconFg;
|
||||
historyReplyCancelFgOver: cancelIconFgOver;
|
||||
historyComposeButtonBg: historyComposeAreaBg;
|
||||
historyComposeButtonBgOver: #f5f5f5;
|
||||
historyComposeButtonBgRipple: #e7e7e7;
|
||||
historyTextInFg: windowTextFg;
|
||||
historyTextOutFg: windowTextFg;
|
||||
historyCaptionInFg: historyTextInFg;
|
||||
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,10,19,6
|
||||
PRODUCTVERSION 0,10,19,6
|
||||
FILEVERSION 0,10,19,7
|
||||
PRODUCTVERSION 0,10,19,7
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -51,10 +51,10 @@ BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileVersion", "0.10.19.6"
|
||||
VALUE "FileVersion", "0.10.19.7"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "0.10.19.6"
|
||||
VALUE "ProductVersion", "0.10.19.7"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,10,19,6
|
||||
PRODUCTVERSION 0,10,19,6
|
||||
FILEVERSION 0,10,19,7
|
||||
PRODUCTVERSION 0,10,19,7
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -43,10 +43,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Updater"
|
||||
VALUE "FileVersion", "0.10.19.6"
|
||||
VALUE "FileVersion", "0.10.19.7"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "0.10.19.6"
|
||||
VALUE "ProductVersion", "0.10.19.7"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -1037,15 +1037,15 @@ void AppClass::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId) {
|
||||
PreparedPhotoThumbs photoThumbs;
|
||||
QVector<MTPPhotoSize> photoSizes;
|
||||
|
||||
QPixmap thumb = App::pixmapFromImageInPlace(tosend.scaled(160, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
auto thumb = App::pixmapFromImageInPlace(tosend.scaled(160, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
photoThumbs.insert('a', thumb);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("a"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
|
||||
|
||||
QPixmap medium = App::pixmapFromImageInPlace(tosend.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
auto medium = App::pixmapFromImageInPlace(tosend.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
photoThumbs.insert('b', medium);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("b"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0)));
|
||||
|
||||
QPixmap full = QPixmap::fromImage(tosend, Qt::ColorOnly);
|
||||
auto full = QPixmap::fromImage(tosend, Qt::ColorOnly);
|
||||
photoThumbs.insert('c', full);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("c"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0)));
|
||||
|
||||
|
@ -31,6 +31,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "ui/filedialog.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "apiwrap.h"
|
||||
|
@ -28,6 +28,10 @@ class FlatLabel;
|
||||
class ConfirmBox;
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class PhoneInput;
|
||||
class InputArea;
|
||||
class UsernameInput;
|
||||
class Checkbox;
|
||||
class Radiobutton;
|
||||
class LinkButton;
|
||||
@ -64,9 +68,9 @@ private:
|
||||
UserData *_user = nullptr;
|
||||
QString _boxTitle;
|
||||
|
||||
ChildWidget<InputField> _first;
|
||||
ChildWidget<InputField> _last;
|
||||
ChildWidget<PhoneInput> _phone;
|
||||
ChildWidget<Ui::InputField> _first;
|
||||
ChildWidget<Ui::InputField> _last;
|
||||
ChildWidget<Ui::PhoneInput> _phone;
|
||||
|
||||
ChildWidget<Ui::RoundButton> _save;
|
||||
ChildWidget<Ui::RoundButton> _cancel;
|
||||
@ -119,8 +123,8 @@ private:
|
||||
Animation _a_photoOver;
|
||||
bool _photoOver;
|
||||
|
||||
ChildWidget<InputField> _title;
|
||||
ChildWidget<InputArea> _description;
|
||||
ChildWidget<Ui::InputField> _title;
|
||||
ChildWidget<Ui::InputArea> _description;
|
||||
|
||||
QImage _photoBig;
|
||||
QPixmap _photoSmall;
|
||||
@ -187,7 +191,7 @@ private:
|
||||
int32 _aboutPublicWidth, _aboutPublicHeight;
|
||||
Text _aboutPublic, _aboutPrivate;
|
||||
|
||||
ChildWidget<UsernameInput> _link;
|
||||
ChildWidget<Ui::UsernameInput> _link;
|
||||
|
||||
QRect _invitationLink;
|
||||
bool _linkOver;
|
||||
@ -236,8 +240,8 @@ private:
|
||||
PeerData *_peer;
|
||||
QString _boxTitle;
|
||||
|
||||
ChildWidget<InputField> _first;
|
||||
ChildWidget<InputField> _last;
|
||||
ChildWidget<Ui::InputField> _first;
|
||||
ChildWidget<Ui::InputField> _last;
|
||||
|
||||
ChildWidget<Ui::RoundButton> _save;
|
||||
ChildWidget<Ui::RoundButton> _cancel;
|
||||
@ -283,8 +287,8 @@ private:
|
||||
|
||||
ChannelData *_channel;
|
||||
|
||||
ChildWidget<InputField> _title;
|
||||
ChildWidget<InputArea> _description;
|
||||
ChildWidget<Ui::InputField> _title;
|
||||
ChildWidget<Ui::InputArea> _description;
|
||||
ChildWidget<Ui::Checkbox> _sign;
|
||||
|
||||
ChildWidget<Ui::LinkButton> _publicLink;
|
||||
|
@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwindow.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
AutoLockBox::AutoLockBox() :
|
||||
_close(this, lang(lng_box_ok), st::defaultBoxButton) {
|
||||
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwindow.h"
|
||||
#include "window/window_theme.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
BackgroundBox::BackgroundBox() : ItemListBox(st::backgroundScroll)
|
||||
, _inner(this) {
|
||||
|
@ -23,6 +23,48 @@ using "basic.style";
|
||||
using "ui/widgets/widgets.style";
|
||||
using "intro/intro.style";
|
||||
|
||||
defaultBoxButton: RoundButton {
|
||||
textFg: #2f9fea;
|
||||
textFgOver: #2f9fea;
|
||||
secondaryTextFg: #2f9fea;
|
||||
secondaryTextFgOver: #2f9fea;
|
||||
textBg: boxBg;
|
||||
textBgOver: lightButtonBgOver;
|
||||
|
||||
width: -24px;
|
||||
height: 36px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
downTextTop: 8px;
|
||||
|
||||
font: boxButtonFont;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: lightButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
||||
cancelBoxButton: RoundButton(defaultBoxButton) {
|
||||
textFg: #aeaeae;
|
||||
}
|
||||
|
||||
attentionBoxButton: RoundButton(defaultBoxButton) {
|
||||
textFg: attentionBoxButtonFg;
|
||||
textFgOver: attentionBoxButtonFgOver;
|
||||
textBgOver: attentionBoxButtonBgOver;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: attentionBoxButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
||||
defaultBoxCheckbox: Checkbox(defaultCheckbox) {
|
||||
width: -46px;
|
||||
textPosition: point(34px, 1px);
|
||||
font: boxTextFont;
|
||||
}
|
||||
|
||||
boxBlockTitleHeight: 48px;
|
||||
boxBlockTitlePosition: point(18px, 14px);
|
||||
boxBlockTitleFont: font(boxFontSize semibold);
|
||||
@ -46,6 +88,8 @@ boxLinkButton: LinkButton {
|
||||
overFont: font(boxFontSize underline);
|
||||
}
|
||||
|
||||
boxOptionListPadding: margins(2px, 20px, 2px, 2px);
|
||||
|
||||
confirmInviteTitle: flatLabel(labelDefFlat) {
|
||||
font: font(16px semibold);
|
||||
align: align(center);
|
||||
@ -281,7 +325,7 @@ sessionTerminateAllButton: LinkButton(boxLinkButton) {
|
||||
|
||||
passcodeHeaderFont: font(19px);
|
||||
passcodeHeaderHeight: 80px;
|
||||
passcodeInput: flatInput(inpIntroPhone) {
|
||||
passcodeInput: FlatInput(introPhone) {
|
||||
}
|
||||
passcodeSubmit: RoundButton(introNextButton) {
|
||||
width: 225px;
|
||||
@ -340,3 +384,45 @@ aboutLabel: flatLabel(labelDefFlat) {
|
||||
aboutTextStyle: textStyle(defaultTextStyle) {
|
||||
lineHeight: 22px;
|
||||
}
|
||||
|
||||
editTextArea: InputArea(defaultInputArea) {
|
||||
textMargins: margins(1px, 6px, 1px, 4px);
|
||||
heightMax: 256px;
|
||||
}
|
||||
|
||||
confirmCaptionArea: InputArea(defaultInputArea) {
|
||||
textMargins: margins(1px, 6px, 1px, 4px);
|
||||
heightMax: 56px;
|
||||
}
|
||||
confirmBg: #f2f2f2;
|
||||
confirmMaxHeight: 245px;
|
||||
confirmCompressedSkip: 10px;
|
||||
|
||||
connectionHostInputField: InputField(defaultInputField) {
|
||||
width: 160px;
|
||||
}
|
||||
connectionPortInputField: InputField(defaultInputField) {
|
||||
width: 55px;
|
||||
}
|
||||
connectionUserInputField: InputField(defaultInputField) {
|
||||
width: 95px;
|
||||
}
|
||||
connectionPasswordInputField: InputField(defaultInputField) {
|
||||
width: 120px;
|
||||
}
|
||||
connectionIPv6Skip: 11px;
|
||||
|
||||
langsWidth: 256px;
|
||||
langsButton: Radiobutton(defaultRadiobutton) {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
backgroundPadding: 10px;
|
||||
backgroundSize: size(108px, 193px);
|
||||
backgroundScroll: flatScroll(boxScroll) {
|
||||
round: 2px;
|
||||
width: 10px;
|
||||
deltax: 3px;
|
||||
deltat: 10px;
|
||||
deltab: 0px;
|
||||
}
|
||||
|
@ -29,6 +29,11 @@ class Checkbox;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace st {
|
||||
extern const style::RoundButton &defaultBoxButton;
|
||||
extern const style::RoundButton &cancelBoxButton;
|
||||
} // namespace style
|
||||
|
||||
class InformBox;
|
||||
class ConfirmBox : public AbstractBox, public ClickHandlerHost {
|
||||
Q_OBJECT
|
||||
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "styles/style_boxes.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "mainwidget.h"
|
||||
#include "lang.h"
|
||||
|
||||
@ -106,7 +107,7 @@ void ConfirmPhoneBox::launch() {
|
||||
}
|
||||
_about->setMarkedText(aboutText);
|
||||
|
||||
_code = new InputField(this, st::confirmPhoneCodeField, lang(lng_code_ph));
|
||||
_code.create(this, st::confirmPhoneCodeField, lang(lng_code_ph));
|
||||
|
||||
_send.create(this, lang(lng_confirm_phone_send), st::defaultBoxButton);
|
||||
_cancel.create(this, lang(lng_cancel), st::cancelBoxButton);
|
||||
@ -300,6 +301,10 @@ void ConfirmPhoneBox::resizeEvent(QResizeEvent *e) {
|
||||
AbstractBox::resizeEvent(e);
|
||||
}
|
||||
|
||||
void ConfirmPhoneBox::doSetInnerFocus() {
|
||||
_code->setFocus();
|
||||
}
|
||||
|
||||
ConfirmPhoneBox::~ConfirmPhoneBox() {
|
||||
if (_sendCodeRequestId) {
|
||||
MTP::cancel(_sendCodeRequestId);
|
||||
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
class FlatLabel;
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
|
||||
@ -47,9 +48,7 @@ protected:
|
||||
void showAll() override {
|
||||
showChildren();
|
||||
}
|
||||
void doSetInnerFocus() override {
|
||||
_code->setFocus();
|
||||
}
|
||||
void doSetInnerFocus() override;
|
||||
|
||||
private:
|
||||
ConfirmPhoneBox(QWidget *parent, const QString &phone, const QString &hash);
|
||||
@ -96,7 +95,7 @@ private:
|
||||
ChildWidget<FlatLabel> _about = { nullptr };
|
||||
ChildWidget<Ui::RoundButton> _send = { nullptr };
|
||||
ChildWidget<Ui::RoundButton> _cancel = { nullptr };
|
||||
ChildWidget<InputField> _code = { nullptr };
|
||||
ChildWidget<Ui::InputField> _code = { nullptr };
|
||||
|
||||
// Flag for not calling onTextChanged() recursively.
|
||||
bool _fixing = false;
|
||||
|
@ -27,7 +27,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwindow.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "history/history_location_manager.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
ConnectionBox::ConnectionBox() : AbstractBox(st::boxWidth)
|
||||
, _hostInput(this, st::connectionHostInputField, lang(lng_connection_host_ph), Global::ConnectionProxy().host)
|
||||
|
@ -23,6 +23,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "abstractbox.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class PortInput;
|
||||
class PasswordInput;
|
||||
class Checkbox;
|
||||
class Radiobutton;
|
||||
class RoundButton;
|
||||
@ -47,10 +50,10 @@ protected:
|
||||
void doSetInnerFocus() override;
|
||||
|
||||
private:
|
||||
ChildWidget<InputField> _hostInput;
|
||||
ChildWidget<PortInput> _portInput;
|
||||
ChildWidget<InputField> _userInput;
|
||||
ChildWidget<PasswordField> _passwordInput;
|
||||
ChildWidget<Ui::InputField> _hostInput;
|
||||
ChildWidget<Ui::PortInput> _portInput;
|
||||
ChildWidget<Ui::InputField> _userInput;
|
||||
ChildWidget<Ui::PasswordInput> _passwordInput;
|
||||
ChildWidget<Ui::Radiobutton> _autoRadio;
|
||||
ChildWidget<Ui::Radiobutton> _httpProxyRadio;
|
||||
ChildWidget<Ui::Radiobutton> _tcpProxyRadio;
|
||||
|
@ -29,6 +29,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "langloaderplain.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
LanguageBox::LanguageBox() :
|
||||
_close(this, lang(lng_box_ok), st::defaultBoxButton) {
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "localstorage.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
|
||||
PasscodeBox::PasscodeBox(bool turningOff) : AbstractBox(st::boxWidth)
|
||||
, _replacedBy(0)
|
||||
|
@ -23,6 +23,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "abstractbox.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
class PasswordInput;
|
||||
class LinkButton;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
@ -81,11 +83,11 @@ private:
|
||||
|
||||
ChildWidget<Ui::RoundButton> _saveButton;
|
||||
ChildWidget<Ui::RoundButton> _cancelButton;
|
||||
ChildWidget<PasswordField> _oldPasscode;
|
||||
ChildWidget<PasswordField> _newPasscode;
|
||||
ChildWidget<PasswordField> _reenterPasscode;
|
||||
ChildWidget<InputField> _passwordHint;
|
||||
ChildWidget<InputField> _recoverEmail;
|
||||
ChildWidget<Ui::PasswordInput> _oldPasscode;
|
||||
ChildWidget<Ui::PasswordInput> _newPasscode;
|
||||
ChildWidget<Ui::PasswordInput> _reenterPasscode;
|
||||
ChildWidget<Ui::InputField> _passwordHint;
|
||||
ChildWidget<Ui::InputField> _recoverEmail;
|
||||
ChildWidget<Ui::LinkButton> _recover;
|
||||
|
||||
QString _oldError, _newError, _emailError;
|
||||
@ -123,7 +125,7 @@ private:
|
||||
|
||||
ChildWidget<Ui::RoundButton> _saveButton;
|
||||
ChildWidget<Ui::RoundButton> _cancelButton;
|
||||
ChildWidget<InputField> _recoverCode;
|
||||
ChildWidget<Ui::InputField> _recoverCode;
|
||||
|
||||
QString _error;
|
||||
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "photocropbox.h"
|
||||
#include "fileuploader.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
PhotoCropBox::PhotoCropBox(const QImage &img, const PeerId &peer) : AbstractBox()
|
||||
, _downState(0)
|
||||
|
@ -28,7 +28,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "history/history_media_types.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxWideWidth)
|
||||
, _file(file)
|
||||
@ -141,7 +143,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
|
||||
|
||||
updateBoxSize();
|
||||
_caption->setMaxLength(MaxPhotoCaption);
|
||||
_caption->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||
_caption->setCtrlEnterSubmit(Ui::CtrlEnterSubmitBoth);
|
||||
connect(_compressed, SIGNAL(changed()), this, SLOT(onCompressedChange()));
|
||||
connect(_caption, SIGNAL(resized()), this, SLOT(onCaptionResized()));
|
||||
connect(_caption, SIGNAL(submitted(bool)), this, SLOT(onSend(bool)));
|
||||
@ -493,13 +495,13 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
|
||||
if (_animated || _photo || _doc) {
|
||||
_field.create(this, st::confirmCaptionArea, lang(lng_photo_caption), caption);
|
||||
_field->setMaxLength(MaxPhotoCaption);
|
||||
_field->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||
_field->setCtrlEnterSubmit(Ui::CtrlEnterSubmitBoth);
|
||||
} else {
|
||||
auto original = msg->originalText();
|
||||
QString text = textApplyEntities(original.text, original.entities);
|
||||
_field.create(this, st::editTextArea, lang(lng_photo_caption), text);
|
||||
// _field->setMaxLength(MaxMessageSize); // entities can make text in input field larger but still valid
|
||||
_field->setCtrlEnterSubmit(cCtrlEnter() ? CtrlEnterSubmitCtrlEnter : CtrlEnterSubmitEnter);
|
||||
_field->setCtrlEnterSubmit(cCtrlEnter() ? Ui::CtrlEnterSubmitCtrlEnter : Ui::CtrlEnterSubmitEnter);
|
||||
}
|
||||
updateBoxSize();
|
||||
connect(_field, SIGNAL(submitted(bool)), this, SLOT(onSave(bool)));
|
||||
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
namespace Ui {
|
||||
class Checkbox;
|
||||
class RoundButton;
|
||||
class InputArea;
|
||||
} // namespace Ui
|
||||
|
||||
class PhotoSendBox : public AbstractBox {
|
||||
@ -57,7 +58,7 @@ private:
|
||||
|
||||
QPixmap _thumb;
|
||||
|
||||
ChildWidget<InputArea> _caption;
|
||||
ChildWidget<Ui::InputArea> _caption;
|
||||
bool _compressedFromSettings;
|
||||
ChildWidget<Ui::Checkbox> _compressed;
|
||||
|
||||
@ -108,7 +109,7 @@ private:
|
||||
|
||||
QPixmap _thumb;
|
||||
|
||||
ChildWidget<InputArea> _field = { nullptr };
|
||||
ChildWidget<Ui::InputArea> _field = { nullptr };
|
||||
ChildWidget<Ui::RoundButton> _save;
|
||||
ChildWidget<Ui::RoundButton> _cancel;
|
||||
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
ReportBox::ReportBox(ChannelData *channel) : AbstractBox(st::boxWidth)
|
||||
@ -75,9 +76,9 @@ void ReportBox::resizeEvent(QResizeEvent *e) {
|
||||
void ReportBox::onChange() {
|
||||
if (_reasonOther->checked()) {
|
||||
if (!_reasonOtherText) {
|
||||
_reasonOtherText = new InputArea(this, st::profileReportReasonOther, lang(lng_report_reason_description));
|
||||
_reasonOtherText.create(this, st::profileReportReasonOther, lang(lng_report_reason_description));
|
||||
_reasonOtherText->show();
|
||||
_reasonOtherText->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||
_reasonOtherText->setCtrlEnterSubmit(Ui::CtrlEnterSubmitBoth);
|
||||
_reasonOtherText->setMaxLength(MaxPhotoCaption);
|
||||
_reasonOtherText->resize(width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), _reasonOtherText->height());
|
||||
|
||||
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
namespace Ui {
|
||||
class Radiobutton;
|
||||
class RoundButton;
|
||||
class InputArea;
|
||||
} // namespace Ui
|
||||
|
||||
class ReportBox : public AbstractBox, public RPCSender {
|
||||
@ -59,7 +60,7 @@ private:
|
||||
ChildWidget<Ui::Radiobutton> _reasonViolence;
|
||||
ChildWidget<Ui::Radiobutton> _reasonPornography;
|
||||
ChildWidget<Ui::Radiobutton> _reasonOther;
|
||||
ChildWidget<InputArea> _reasonOtherText = { nullptr };
|
||||
ChildWidget<Ui::InputArea> _reasonOtherText = { nullptr };
|
||||
|
||||
ChildWidget<Ui::RoundButton> _report, _cancel;
|
||||
|
||||
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
UsernameBox::UsernameBox() : AbstractBox(st::boxWidth),
|
||||
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "abstractbox.h"
|
||||
|
||||
namespace Ui {
|
||||
class UsernameInput;
|
||||
class RoundButton;
|
||||
class LinkButton;
|
||||
} // namespace Ui
|
||||
@ -60,7 +61,7 @@ private:
|
||||
|
||||
ChildWidget<Ui::RoundButton> _save;
|
||||
ChildWidget<Ui::RoundButton> _cancel;
|
||||
ChildWidget<UsernameInput> _username;
|
||||
ChildWidget<Ui::UsernameInput> _username;
|
||||
ChildWidget<Ui::LinkButton> _link;
|
||||
|
||||
mtpRequestId _saveRequestId, _checkRequestId;
|
||||
|
@ -651,10 +651,19 @@ bool Generator::writeIncludesInSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = module_.enumIncludes([this](const Module &module) -> bool {
|
||||
source_->include(moduleBaseName(module) + ".h");
|
||||
auto includes = QStringList();
|
||||
std::function<bool(const Module&)> collector = [this, &collector, &includes](const Module &module) {
|
||||
module.enumIncludes(collector);
|
||||
auto base = moduleBaseName(module);
|
||||
if (!includes.contains(base)) {
|
||||
includes.push_back(base);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
auto result = module_.enumIncludes(collector);
|
||||
for (auto base : includes) {
|
||||
source_->include(base + ".h");
|
||||
}
|
||||
source_->newline();
|
||||
return result;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "core/utils.h"
|
||||
|
||||
#define BETA_VERSION_MACRO (10019006ULL)
|
||||
#define BETA_VERSION_MACRO (10019007ULL)
|
||||
|
||||
constexpr int AppVersion = 10020;
|
||||
constexpr str_const AppVersionStr = "0.10.20";
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "data/data_drafts.h"
|
||||
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "historywidget.h"
|
||||
#include "mainwidget.h"
|
||||
#include "localstorage.h"
|
||||
@ -30,6 +31,13 @@ namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
Draft::Draft(const Ui::FlatTextarea *field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequestId)
|
||||
: textWithTags(field->getTextWithTags())
|
||||
, msgId(msgId)
|
||||
, cursor(field)
|
||||
, previewCancelled(previewCancelled) {
|
||||
}
|
||||
|
||||
void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) {
|
||||
auto history = App::history(peerId);
|
||||
auto text = qs(draft.vmessage);
|
||||
|
@ -20,6 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Ui {
|
||||
class FlatTextarea;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
|
||||
void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft);
|
||||
@ -35,12 +39,8 @@ struct Draft {
|
||||
, previewCancelled(previewCancelled)
|
||||
, saveRequestId(saveRequestId) {
|
||||
}
|
||||
Draft(const FlatTextarea *field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequestId = 0)
|
||||
: textWithTags(field->getTextWithTags())
|
||||
, msgId(msgId)
|
||||
, cursor(field)
|
||||
, previewCancelled(previewCancelled) {
|
||||
}
|
||||
Draft(const Ui::FlatTextarea *field, MsgId msgId, bool previewCancelled, mtpRequestId saveRequestId = 0);
|
||||
|
||||
QDateTime date;
|
||||
TextWithTags textWithTags;
|
||||
MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft
|
||||
|
@ -84,6 +84,10 @@ dialogsMenuToggle: IconButton {
|
||||
iconOver: icon {{ "dialogs_menu", dialogsMenuIconFgOver }};
|
||||
iconPosition: point(6px, 6px);
|
||||
iconPositionDown: point(6px, 6px);
|
||||
|
||||
rippleAreaPosition: point(0px, 0px);
|
||||
rippleAreaSize: 32px;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
dialogsLock: IconButton(dialogsMenuToggle) {
|
||||
icon: icon {{ "dialogs_lock", dialogsMenuIconFg }};
|
||||
@ -92,7 +96,7 @@ dialogsLock: IconButton(dialogsMenuToggle) {
|
||||
dialogsUnlockIcon: icon {{ "dialogs_unlock", dialogsMenuIconFg }};
|
||||
dialogsUnlockIconOver: icon {{ "dialogs_unlock", dialogsMenuIconFgOver }};
|
||||
|
||||
dialogsFilter: flatInput(inpDefGray) {
|
||||
dialogsFilter: FlatInput(defaultFlatInput) {
|
||||
font: font(fsize);
|
||||
bgColor: #f2f2f2;
|
||||
phColor: #949494;
|
||||
@ -102,9 +106,15 @@ dialogsFilter: flatInput(inpDefGray) {
|
||||
height: 32px;
|
||||
textMrg: margins(12px, 3px, 30px, 3px);
|
||||
}
|
||||
dialogsCancelSearch: IconButton(dialogsMenuToggle) {
|
||||
icon: icon {{ "dialogs_cancel_search", dialogsMenuIconFg, point(0px, 1px) }};
|
||||
iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver, point(0px, 1px) }};
|
||||
dialogsCancelSearchInPeer: IconButton(dialogsMenuToggle) {
|
||||
icon: icon {{ "dialogs_cancel_search", dialogsMenuIconFg }};
|
||||
iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver }};
|
||||
|
||||
iconPosition: point(7px, 7px);
|
||||
iconPositionDown: point(7px, 7px);
|
||||
}
|
||||
dialogsCancelSearch: IconButton(dialogsCancelSearchInPeer) {
|
||||
rippleAreaSize: 0px;
|
||||
}
|
||||
|
||||
dialogsMenu: Menu(defaultMenu) {
|
||||
@ -183,6 +193,10 @@ dialogsUpdateButton: FlatButton {
|
||||
|
||||
font: semiboldFont;
|
||||
overFont: semiboldFont;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: activeButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
||||
dialogsForwardHeight: 32px;
|
||||
|
@ -40,6 +40,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "localstorage.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "autoupdater.h"
|
||||
|
||||
DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(parent)
|
||||
@ -47,7 +48,7 @@ DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(pare
|
||||
, contactsNoDialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||
, contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||
, _cancelSearchInPeer(this, st::dialogsCancelSearch) {
|
||||
, _cancelSearchInPeer(this, st::dialogsCancelSearchInPeer) {
|
||||
if (Global::DialogsModeEnabled()) {
|
||||
importantDialogs = std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ class PopupMenu;
|
||||
class DropdownMenu;
|
||||
class FlatButton;
|
||||
class LinkButton;
|
||||
class FlatInput;
|
||||
} // namespace Ui
|
||||
|
||||
enum DialogsSearchRequestType {
|
||||
@ -332,7 +333,7 @@ private:
|
||||
ChildWidget<Ui::IconButton> _forwardCancel = { nullptr };
|
||||
ChildWidget<Ui::IconButton> _mainMenuToggle;
|
||||
ChildWidget<Ui::DropdownMenu> _mainMenu = { nullptr };
|
||||
ChildWidget<FlatInput> _filter;
|
||||
ChildWidget<Ui::FlatInput> _filter;
|
||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||
ChildWidget<Ui::IconButton> _lockUnlock;
|
||||
ChildWidget<ScrollArea> _scroll;
|
||||
|
@ -152,7 +152,30 @@ struct SendAction {
|
||||
int32 progress;
|
||||
};
|
||||
|
||||
using TextWithTags = FlatTextarea::TextWithTags;
|
||||
struct TextWithTags {
|
||||
struct Tag {
|
||||
int offset, length;
|
||||
QString id;
|
||||
};
|
||||
using Tags = QVector<Tag>;
|
||||
|
||||
QString text;
|
||||
Tags tags;
|
||||
};
|
||||
|
||||
inline bool operator==(const TextWithTags::Tag &a, const TextWithTags::Tag &b) {
|
||||
return (a.offset == b.offset) && (a.length == b.length) && (a.id == b.id);
|
||||
}
|
||||
inline bool operator!=(const TextWithTags::Tag &a, const TextWithTags::Tag &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator==(const TextWithTags &a, const TextWithTags &b) {
|
||||
return (a.text == b.text) && (a.tags == b.tags);
|
||||
}
|
||||
inline bool operator!=(const TextWithTags &a, const TextWithTags &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
namespace Data {
|
||||
struct Draft;
|
||||
|
@ -136,7 +136,7 @@ historyPeer8UserpicBg: #f7b37c;
|
||||
historyPeer8UserpicFg: #de8d62;
|
||||
historyPeer8UserpicPerson: icon {{ size(120px, 120px), historyPeer8UserpicBg }, { "userpic_person", historyPeer8UserpicFg }};
|
||||
|
||||
historyComposeField: flatTextarea {
|
||||
historyComposeField: FlatTextarea {
|
||||
textColor: #000000;
|
||||
bgColor: historyComposeAreaBg;
|
||||
align: align(left);
|
||||
@ -170,12 +170,16 @@ historyComposeButton: FlatButton {
|
||||
width: -32px;
|
||||
height: 46px;
|
||||
|
||||
textTop: 12px;
|
||||
overTextTop: 12px;
|
||||
downTextTop: 13px;
|
||||
textTop: 14px;
|
||||
overTextTop: 14px;
|
||||
downTextTop: 14px;
|
||||
|
||||
font: semiboldFont;
|
||||
overFont: semiboldFont;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: historyComposeButtonBgRipple;
|
||||
}
|
||||
}
|
||||
historyUnblock: FlatButton(historyComposeButton) {
|
||||
color: #d15948;
|
||||
@ -290,23 +294,6 @@ historyInlineBotCancel: IconButton(historyReplyCancel) {
|
||||
height: 46px;
|
||||
}
|
||||
|
||||
topBarSearch: IconButton {
|
||||
width: 44px;
|
||||
height: topBarHeight;
|
||||
|
||||
icon: icon {{ "title_search", menuIconFg }};
|
||||
iconOver: icon {{ "title_search", menuIconFgOver }};
|
||||
|
||||
iconPosition: point(13px, 18px);
|
||||
iconPositionDown: point(13px, 18px);
|
||||
}
|
||||
topBarMenuToggle: IconButton(topBarSearch) {
|
||||
icon: icon {{ "title_menu_dots", menuIconFg }};
|
||||
iconOver: icon {{ "title_menu_dots", menuIconFgOver }};
|
||||
|
||||
iconPosition: point(18px, 17px);
|
||||
iconPositionDown: point(18px, 17px);
|
||||
}
|
||||
reportSpamHide: FlatButton {
|
||||
duration: 200;
|
||||
cursor: cursor(pointer);
|
||||
@ -327,17 +314,6 @@ reportSpamHide: FlatButton {
|
||||
font: font(fsize);
|
||||
overFont: font(fsize underline);
|
||||
}
|
||||
reportSpamButton: FlatButton(reportSpamHide) {
|
||||
textTop: 6px;
|
||||
overTextTop: 6px;
|
||||
downTextTop: 7px;
|
||||
|
||||
width: -50px;
|
||||
height: 30px;
|
||||
|
||||
bgColor: #888888;
|
||||
overBgColor: #7b7b7b;
|
||||
}
|
||||
reportSpamSeparator: 30px;
|
||||
reportSpamBg: #fffffff0;
|
||||
reportSpamFg: #000000;
|
||||
|
@ -23,6 +23,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/photosendbox.h"
|
||||
#include "boxes/sharebox.h"
|
||||
@ -77,13 +79,13 @@ QMimeData *mimeDataFromTextWithEntities(const TextWithEntities &forClipboard) {
|
||||
for (auto &tag : tags) {
|
||||
tag.id = mimeTagFromTag(tag.id);
|
||||
}
|
||||
result->setData(FlatTextarea::tagsMimeType(), FlatTextarea::serializeTagsList(tags));
|
||||
result->setData(Ui::FlatTextarea::tagsMimeType(), Ui::FlatTextarea::serializeTagsList(tags));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// For mention tags save and validate userId, ignore tags for different userId.
|
||||
class FieldTagMimeProcessor : public FlatTextarea::TagMimeProcessor {
|
||||
class FieldTagMimeProcessor : public Ui::FlatTextarea::TagMimeProcessor {
|
||||
public:
|
||||
QString mimeTagFromTag(const QString &tagId) override {
|
||||
return ::mimeTagFromTag(tagId);
|
||||
@ -2302,7 +2304,7 @@ void HistoryInner::onParentGeometryChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
MessageField::MessageField(HistoryWidget *history, const style::flatTextarea &st, const QString &ph, const QString &val) : FlatTextarea(history, st, ph, val), history(history) {
|
||||
MessageField::MessageField(HistoryWidget *history, const style::FlatTextarea &st, const QString &ph, const QString &val) : Ui::FlatTextarea(history, st, ph, val), history(history) {
|
||||
setMinHeight(st::historySend.height - 2 * st::historySendPadding);
|
||||
setMaxHeight(st::historyComposeFieldMaxHeight);
|
||||
}
|
||||
@ -2976,7 +2978,7 @@ QPoint SilentToggle::tooltipPos() const {
|
||||
return QCursor::pos();
|
||||
}
|
||||
|
||||
EntitiesInText entitiesFromTextTags(const FlatTextarea::TagList &tags) {
|
||||
EntitiesInText entitiesFromTextTags(const TextWithTags::Tags &tags) {
|
||||
EntitiesInText result;
|
||||
if (tags.isEmpty()) {
|
||||
return result;
|
||||
@ -3229,14 +3231,14 @@ void HistoryWidget::updateInlineBotQuery() {
|
||||
MTP::cancel(_inlineBotResolveRequestId);
|
||||
_inlineBotResolveRequestId = 0;
|
||||
}
|
||||
if (bot == LookingUpInlineBot) {
|
||||
_inlineBot = LookingUpInlineBot;
|
||||
if (bot == Ui::LookingUpInlineBot) {
|
||||
_inlineBot = Ui::LookingUpInlineBot;
|
||||
// Notify::inlineBotRequesting(true);
|
||||
_inlineBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_inlineBotUsername)), rpcDone(&HistoryWidget::inlineBotResolveDone), rpcFail(&HistoryWidget::inlineBotResolveFail, _inlineBotUsername));
|
||||
return;
|
||||
}
|
||||
} else if (bot == LookingUpInlineBot) {
|
||||
if (_inlineBot == LookingUpInlineBot) {
|
||||
} else if (bot == Ui::LookingUpInlineBot) {
|
||||
if (_inlineBot == Ui::LookingUpInlineBot) {
|
||||
return;
|
||||
}
|
||||
bot = _inlineBot;
|
||||
@ -4389,11 +4391,11 @@ void HistoryWidget::updateAfterDrag() {
|
||||
}
|
||||
|
||||
void HistoryWidget::updateFieldSubmitSettings() {
|
||||
FlatTextarea::SubmitSettings settings = FlatTextarea::SubmitSettings::Enter;
|
||||
auto settings = Ui::FlatTextarea::SubmitSettings::Enter;
|
||||
if (_inlineBotCancel) {
|
||||
settings = FlatTextarea::SubmitSettings::None;
|
||||
settings = Ui::FlatTextarea::SubmitSettings::None;
|
||||
} else if (cCtrlEnter()) {
|
||||
settings = FlatTextarea::SubmitSettings::CtrlEnter;
|
||||
settings = Ui::FlatTextarea::SubmitSettings::CtrlEnter;
|
||||
}
|
||||
_field->setSubmitSettings(settings);
|
||||
}
|
||||
@ -5156,9 +5158,9 @@ void HistoryWidget::preloadHistoryIfNeeded() {
|
||||
void HistoryWidget::onInlineBotCancel() {
|
||||
auto &textWithTags = _field->getTextWithTags();
|
||||
if (textWithTags.text.size() > _inlineBotUsername.size() + 2) {
|
||||
setFieldText({ '@' + _inlineBotUsername + ' ', TextWithTags::Tags() }, TextUpdateEvent::SaveDraft, FlatTextarea::AddToUndoHistory);
|
||||
setFieldText({ '@' + _inlineBotUsername + ' ', TextWithTags::Tags() }, TextUpdateEvent::SaveDraft, Ui::FlatTextarea::AddToUndoHistory);
|
||||
} else {
|
||||
clearFieldText(TextUpdateEvent::SaveDraft, FlatTextarea::AddToUndoHistory);
|
||||
clearFieldText(TextUpdateEvent::SaveDraft, Ui::FlatTextarea::AddToUndoHistory);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5883,7 +5885,7 @@ bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) {
|
||||
auto &textWithTags = _field->getTextWithTags();
|
||||
if (specialGif) {
|
||||
if (textWithTags.text.trimmed() == '@' + cInlineGifBotUsername() && textWithTags.text.at(0) == '@') {
|
||||
clearFieldText(TextUpdateEvent::SaveDraft, FlatTextarea::AddToUndoHistory);
|
||||
clearFieldText(TextUpdateEvent::SaveDraft, Ui::FlatTextarea::AddToUndoHistory);
|
||||
}
|
||||
} else {
|
||||
TextWithTags textWithTagsToSet;
|
||||
@ -5905,7 +5907,7 @@ bool HistoryWidget::insertBotCommand(const QString &cmd, bool specialGif) {
|
||||
}
|
||||
} else {
|
||||
if (!specialGif || _field->isEmpty()) {
|
||||
setFieldText({ toInsert, TextWithTags::Tags() }, TextUpdateEvent::SaveDraft, FlatTextarea::AddToUndoHistory);
|
||||
setFieldText({ toInsert, TextWithTags::Tags() }, TextUpdateEvent::SaveDraft, Ui::FlatTextarea::AddToUndoHistory);
|
||||
_field->setFocus();
|
||||
return true;
|
||||
}
|
||||
@ -6027,7 +6029,7 @@ void HistoryWidget::inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result)
|
||||
QString inlineBotUsername;
|
||||
auto query = _field->getInlineBotQuery(&bot, &inlineBotUsername);
|
||||
if (inlineBotUsername == _inlineBotUsername) {
|
||||
if (bot == LookingUpInlineBot) {
|
||||
if (bot == Ui::LookingUpInlineBot) {
|
||||
bot = resolvedBot;
|
||||
}
|
||||
} else {
|
||||
@ -6223,7 +6225,7 @@ void HistoryWidget::onKbToggle(bool manual) {
|
||||
}
|
||||
|
||||
void HistoryWidget::onCmdStart() {
|
||||
setFieldText({ qsl("/"), TextWithTags::Tags() }, 0, FlatTextarea::AddToUndoHistory);
|
||||
setFieldText({ qsl("/"), TextWithTags::Tags() }, 0, Ui::FlatTextarea::AddToUndoHistory);
|
||||
}
|
||||
|
||||
void HistoryWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||
@ -6502,7 +6504,7 @@ void HistoryWidget::clearInlineBot() {
|
||||
}
|
||||
|
||||
void HistoryWidget::inlineBotChanged() {
|
||||
bool isInlineBot = _inlineBot && (_inlineBot != LookingUpInlineBot);
|
||||
bool isInlineBot = _inlineBot && (_inlineBot != Ui::LookingUpInlineBot);
|
||||
if (isInlineBot && !_inlineBotCancel) {
|
||||
_inlineBotCancel = std_::make_unique<Ui::IconButton>(this, st::historyInlineBotCancel);
|
||||
connect(_inlineBotCancel.get(), SIGNAL(clicked()), this, SLOT(onInlineBotCancel()));
|
||||
@ -6532,7 +6534,7 @@ void HistoryWidget::onCheckFieldAutocomplete() {
|
||||
if (!_history || _a_show.animating()) return;
|
||||
|
||||
bool start = false;
|
||||
bool isInlineBot = _inlineBot && (_inlineBot != LookingUpInlineBot);
|
||||
bool isInlineBot = _inlineBot && (_inlineBot != Ui::LookingUpInlineBot);
|
||||
QString query = isInlineBot ? QString() : _field->getMentionHashtagBotCommandPart(start);
|
||||
if (!query.isEmpty()) {
|
||||
if (query.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtagsAndBots();
|
||||
@ -6547,7 +6549,7 @@ void HistoryWidget::updateFieldPlaceholder() {
|
||||
_field->setPlaceholder(lang(lng_edit_message_text));
|
||||
_send->setIcon(&st::historyEditSaveIcon, &st::historyEditSaveIconOver);
|
||||
} else {
|
||||
if (_inlineBot && _inlineBot != LookingUpInlineBot) {
|
||||
if (_inlineBot && _inlineBot != Ui::LookingUpInlineBot) {
|
||||
_field->setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
|
||||
} else {
|
||||
_field->setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent->checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph));
|
||||
@ -7770,7 +7772,7 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
|
||||
_field->setFocus();
|
||||
}
|
||||
|
||||
void HistoryWidget::setFieldText(const TextWithTags &textWithTags, TextUpdateEvents events, FlatTextarea::UndoHistoryAction undoHistoryAction) {
|
||||
void HistoryWidget::setFieldText(const TextWithTags &textWithTags, TextUpdateEvents events, Ui::FlatTextarea::UndoHistoryAction undoHistoryAction) {
|
||||
_textUpdateEvents = events;
|
||||
_field->setTextWithTags(textWithTags, undoHistoryAction);
|
||||
_field->moveCursor(QTextCursor::End);
|
||||
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "localimageloader.h"
|
||||
#include "ui/effects/rect_shadow.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "history/history_common.h"
|
||||
#include "history/field_autocomplete.h"
|
||||
#include "window/section_widget.h"
|
||||
@ -310,11 +311,11 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class MessageField : public FlatTextarea {
|
||||
class MessageField : public Ui::FlatTextarea {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MessageField(HistoryWidget *history, const style::flatTextarea &st, const QString &ph = QString(), const QString &val = QString());
|
||||
MessageField(HistoryWidget *history, const style::FlatTextarea &st, const QString &ph = QString(), const QString &val = QString());
|
||||
void dropEvent(QDropEvent *e);
|
||||
bool canInsertFromMimeData(const QMimeData *source) const;
|
||||
void insertFromMimeData(const QMimeData *source);
|
||||
@ -1014,8 +1015,8 @@ private:
|
||||
|
||||
void writeDrafts(Data::Draft **localDraft, Data::Draft **editDraft);
|
||||
void writeDrafts(History *history);
|
||||
void setFieldText(const TextWithTags &textWithTags, TextUpdateEvents events = 0, FlatTextarea::UndoHistoryAction undoHistoryAction = FlatTextarea::ClearUndoHistory);
|
||||
void clearFieldText(TextUpdateEvents events = 0, FlatTextarea::UndoHistoryAction undoHistoryAction = FlatTextarea::ClearUndoHistory) {
|
||||
void setFieldText(const TextWithTags &textWithTags, TextUpdateEvents events = 0, Ui::FlatTextarea::UndoHistoryAction undoHistoryAction = Ui::FlatTextarea::ClearUndoHistory);
|
||||
void clearFieldText(TextUpdateEvents events = 0, Ui::FlatTextarea::UndoHistoryAction undoHistoryAction = Ui::FlatTextarea::ClearUndoHistory) {
|
||||
setFieldText(TextWithTags(), events, undoHistoryAction);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ introCountry: countryInput {
|
||||
bgColor: #f2f2f2;
|
||||
ptrSize: size(15px, 8px);
|
||||
textMrg: margins(16px, 5px, 16px, 15px);
|
||||
font: inpDefFont;
|
||||
font: defaultInputFont;
|
||||
align: align(left);
|
||||
}
|
||||
|
||||
@ -89,17 +89,17 @@ introNextButton: RoundButton(defaultActiveButton) {
|
||||
}
|
||||
|
||||
introPhoneTop: 8px;
|
||||
inpIntroCountryCode: flatInput(inpDefGray) {
|
||||
introCountryCode: FlatInput(defaultFlatInput) {
|
||||
width: 70px;
|
||||
height: 41px;
|
||||
align: align(center);
|
||||
}
|
||||
inpIntroPhone: flatInput(inpDefGray) {
|
||||
introPhone: FlatInput(defaultFlatInput) {
|
||||
textMrg: margins(12px, 5px, 12px, 6px);
|
||||
width: 225px;
|
||||
height: 41px;
|
||||
}
|
||||
inpIntroCode: flatInput(inpDefGray) {
|
||||
introCode: FlatInput(defaultFlatInput) {
|
||||
textMrg: margins(12px, 5px, 12px, 6px);
|
||||
width: 106px;
|
||||
height: 41px;
|
||||
@ -109,10 +109,10 @@ inpIntroCode: flatInput(inpDefGray) {
|
||||
phAlign: align(center);
|
||||
phShift: 0px;
|
||||
}
|
||||
inpIntroName: flatInput(inpIntroPhone) {
|
||||
introName: FlatInput(introPhone) {
|
||||
width: 192px;
|
||||
}
|
||||
inpIntroPassword: flatInput(inpIntroPhone) {
|
||||
introPassword: FlatInput(introPhone) {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_intro.h"
|
||||
|
||||
CodeInput::CodeInput(QWidget *parent, const style::flatInput &st, const QString &ph) : FlatInput(parent, st, ph) {
|
||||
CodeInput::CodeInput(QWidget *parent, const style::FlatInput &st, const QString &ph) : Ui::FlatInput(parent, st, ph) {
|
||||
}
|
||||
|
||||
void CodeInput::correctValue(const QString &was, QString &now) {
|
||||
@ -80,7 +80,7 @@ IntroCode::IntroCode(IntroWidget *parent) : IntroStep(parent)
|
||||
, _desc(st::introTextSize.width())
|
||||
, _noTelegramCode(this, lang(lng_code_no_telegram), st::introLink)
|
||||
, _noTelegramCodeRequestId(0)
|
||||
, _code(this, st::inpIntroCode, lang(lng_code_ph))
|
||||
, _code(this, st::introCode, lang(lng_code_ph))
|
||||
, _callTimer(this)
|
||||
, _callStatus(intro()->getCallStatus())
|
||||
, _checkRequest(this) {
|
||||
|
@ -21,19 +21,18 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "intro/introwidget.h"
|
||||
|
||||
class FlatInput;
|
||||
#include "ui/widgets/input_fields.h"
|
||||
|
||||
namespace Ui {
|
||||
class RoundButton;
|
||||
class LinkButton;
|
||||
} // namespace Ui
|
||||
|
||||
class CodeInput final : public FlatInput {
|
||||
class CodeInput final : public Ui::FlatInput {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CodeInput(QWidget *parent, const style::flatInput &st, const QString &ph);
|
||||
CodeInput(QWidget *parent, const style::FlatInput &st, const QString &ph);
|
||||
|
||||
signals:
|
||||
void codeEntered();
|
||||
|
@ -49,8 +49,8 @@ IntroPhone::IntroPhone(IntroWidget *parent) : IntroStep(parent)
|
||||
, _a_error(animation(this, &IntroPhone::step_error))
|
||||
, _next(this, lang(lng_intro_next), st::introNextButton)
|
||||
, _country(this, st::introCountry)
|
||||
, _phone(this, st::inpIntroPhone)
|
||||
, _code(this, st::inpIntroCountryCode)
|
||||
, _phone(this, st::introPhone)
|
||||
, _code(this, st::introCountryCode)
|
||||
, _signup(this, lng_phone_notreg(lt_signup_start, textcmdStartLink(1), lt_signup_end, textcmdStopLink()), FlatLabel::InitType::Rich, st::introErrorLabel, st::introErrorLabelTextStyle)
|
||||
, _checkRequest(this) {
|
||||
setVisible(false);
|
||||
@ -110,7 +110,7 @@ void IntroPhone::resizeEvent(QResizeEvent *e) {
|
||||
_next->move((width() - _next->width()) / 2, st::introBtnTop);
|
||||
_country->move((width() - _country->width()) / 2, st::introTextTop + st::introTextSize.height() + st::introCountry.top);
|
||||
int phoneTop = _country->y() + _country->height() + st::introPhoneTop;
|
||||
_phone->move((width() - _country->width()) / 2 + _country->width() - st::inpIntroPhone.width, phoneTop);
|
||||
_phone->move((width() - _country->width()) / 2 + _country->width() - st::introPhone.width, phoneTop);
|
||||
_code->move((width() - _country->width()) / 2, phoneTop);
|
||||
}
|
||||
_signup->move((width() - _signup->width()) / 2, _next->y() + _next->height() + st::introErrorTop - ((st::introErrorLabelTextStyle.lineHeight - st::introErrorFont->height) / 2));
|
||||
|
@ -25,6 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "intro/introwidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class PhonePartInput;
|
||||
class CountryCodeInput;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
|
||||
@ -76,8 +78,8 @@ private:
|
||||
QRect _textRect;
|
||||
|
||||
ChildWidget<CountryInput> _country;
|
||||
ChildWidget<PhonePartInput> _phone;
|
||||
ChildWidget<CountryCodeInput> _code;
|
||||
ChildWidget<Ui::PhonePartInput> _phone;
|
||||
ChildWidget<Ui::CountryCodeInput> _code;
|
||||
|
||||
ChildWidget<FlatLabel> _signup;
|
||||
QPixmap _signupCache;
|
||||
|
@ -22,12 +22,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "intro/intropwdcheck.h"
|
||||
|
||||
#include "styles/style_intro.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/filedialog.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "lang.h"
|
||||
#include "application.h"
|
||||
#include "intro/introsignup.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
|
||||
IntroPwdCheck::IntroPwdCheck(IntroWidget *parent) : IntroStep(parent)
|
||||
, a_errorAlpha(0)
|
||||
@ -36,8 +38,8 @@ IntroPwdCheck::IntroPwdCheck(IntroWidget *parent) : IntroStep(parent)
|
||||
, _salt(parent->getPwdSalt())
|
||||
, _hasRecovery(parent->getHasRecovery())
|
||||
, _hint(parent->getPwdHint())
|
||||
, _pwdField(this, st::inpIntroPassword, lang(lng_signin_password))
|
||||
, _codeField(this, st::inpIntroPassword, lang(lng_signin_code))
|
||||
, _pwdField(this, st::introPassword, lang(lng_signin_password))
|
||||
, _codeField(this, st::introPassword, lang(lng_signin_code))
|
||||
, _toRecover(this, lang(lng_signin_recover))
|
||||
, _toPassword(this, lang(lng_signin_try_password))
|
||||
, _reset(this, lang(lng_signin_reset_account), st::introResetLink)
|
||||
|
@ -22,9 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "intro/introwidget.h"
|
||||
|
||||
class FlatInput;
|
||||
|
||||
namespace Ui {
|
||||
class FlatInput;
|
||||
class RoundButton;
|
||||
class LinkButton;
|
||||
} // namespace Ui
|
||||
@ -80,8 +79,8 @@ private:
|
||||
bool _hasRecovery;
|
||||
QString _hint, _emailPattern;
|
||||
|
||||
ChildWidget<FlatInput> _pwdField;
|
||||
ChildWidget<FlatInput> _codeField;
|
||||
ChildWidget<Ui::FlatInput> _pwdField;
|
||||
ChildWidget<Ui::FlatInput> _codeField;
|
||||
ChildWidget<Ui::LinkButton> _toRecover;
|
||||
ChildWidget<Ui::LinkButton> _toPassword;
|
||||
ChildWidget<Ui::LinkButton> _reset;
|
||||
|
@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "lang.h"
|
||||
#include "application.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
|
||||
IntroSignup::IntroSignup(IntroWidget *parent) : IntroStep(parent)
|
||||
, a_errorAlpha(0)
|
||||
@ -35,8 +36,8 @@ IntroSignup::IntroSignup(IntroWidget *parent) : IntroStep(parent)
|
||||
, _a_error(animation(this, &IntroSignup::step_error))
|
||||
, _a_photo(animation(this, &IntroSignup::step_photo))
|
||||
, _next(this, lang(lng_intro_finish), st::introNextButton)
|
||||
, _first(this, st::inpIntroName, lang(lng_signup_firstname))
|
||||
, _last(this, st::inpIntroName, lang(lng_signup_lastname))
|
||||
, _first(this, st::introName, lang(lng_signup_firstname))
|
||||
, _last(this, st::introName, lang(lng_signup_lastname))
|
||||
, _invertOrder(langFirstNameGoesSecond())
|
||||
, _checkRequest(this) {
|
||||
setVisible(false);
|
||||
|
@ -20,11 +20,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/flatinput.h"
|
||||
#include "intro/introwidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class RoundButton;
|
||||
class FlatInput;
|
||||
} // namespace Ui
|
||||
|
||||
class IntroSignup final : public IntroStep {
|
||||
@ -72,8 +72,8 @@ private:
|
||||
QPixmap _photoSmall;
|
||||
int32 _phLeft, _phTop;
|
||||
|
||||
ChildWidget<FlatInput> _first;
|
||||
ChildWidget<FlatInput> _last;
|
||||
ChildWidget<Ui::FlatInput> _first;
|
||||
ChildWidget<Ui::FlatInput> _last;
|
||||
QString _firstName, _lastName;
|
||||
mtpRequestId _sentRequest = 0;
|
||||
|
||||
|
@ -37,6 +37,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "styles/style_intro.h"
|
||||
#include "autoupdater.h"
|
||||
#include "window/slide_animation.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
IntroWidget::IntroWidget(QWidget *parent) : TWidget(parent)
|
||||
, _a_stage(animation(this, &IntroWidget::step_stage))
|
||||
|
@ -353,22 +353,22 @@ void FileLoadTask::process() {
|
||||
}
|
||||
|
||||
if (!fullimage.isNull() && fullimage.width() > 0 && !song && !gif && !voice) {
|
||||
int32 w = fullimage.width(), h = fullimage.height();
|
||||
auto w = fullimage.width(), h = fullimage.height();
|
||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
||||
|
||||
if (w < 20 * h && h < 20 * w) {
|
||||
if (animated) {
|
||||
attributes.push_back(MTP_documentAttributeAnimated());
|
||||
} else if (_type != PrepareDocument) {
|
||||
QPixmap thumb = (w > 100 || h > 100) ? App::pixmapFromImageInPlace(fullimage.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
auto thumb = (w > 100 || h > 100) ? App::pixmapFromImageInPlace(fullimage.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
photoThumbs.insert('s', thumb);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
|
||||
|
||||
QPixmap medium = (w > 320 || h > 320) ? App::pixmapFromImageInPlace(fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
auto medium = (w > 320 || h > 320) ? App::pixmapFromImageInPlace(fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
photoThumbs.insert('m', medium);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0)));
|
||||
|
||||
QPixmap full = (w > 1280 || h > 1280) ? App::pixmapFromImageInPlace(fullimage.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
auto full = (w > 1280 || h > 1280) ? App::pixmapFromImageInPlace(fullimage.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation)) : QPixmap::fromImage(fullimage);
|
||||
photoThumbs.insert('y', full);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("y"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0)));
|
||||
|
||||
|
@ -32,6 +32,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwindow.h"
|
||||
#include "lang.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "application.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
@ -2369,8 +2370,8 @@ void writeDrafts(const PeerId &peer, const MessageDraft &localDraft, const Messa
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
|
||||
auto msgTags = FlatTextarea::serializeTagsList(localDraft.textWithTags.tags);
|
||||
auto editTags = FlatTextarea::serializeTagsList(editDraft.textWithTags.tags);
|
||||
auto msgTags = Ui::FlatTextarea::serializeTagsList(localDraft.textWithTags.tags);
|
||||
auto editTags = Ui::FlatTextarea::serializeTagsList(editDraft.textWithTags.tags);
|
||||
|
||||
int size = sizeof(quint64);
|
||||
size += Serialize::stringSize(localDraft.textWithTags.text) + Serialize::bytearraySize(msgTags) + 2 * sizeof(qint32);
|
||||
@ -2476,8 +2477,8 @@ void readDraftsWithCursors(History *h) {
|
||||
return;
|
||||
}
|
||||
|
||||
msgData.tags = FlatTextarea::deserializeTagsList(msgTagsSerialized, msgData.text.size());
|
||||
editData.tags = FlatTextarea::deserializeTagsList(editTagsSerialized, editData.text.size());
|
||||
msgData.tags = Ui::FlatTextarea::deserializeTagsList(msgTagsSerialized, msgData.text.size());
|
||||
editData.tags = Ui::FlatTextarea::deserializeTagsList(editTagsSerialized, editData.text.size());
|
||||
|
||||
MessageCursor msgCursor, editCursor;
|
||||
_readDraftCursors(peer, msgCursor, editCursor);
|
||||
|
@ -84,7 +84,6 @@ int32 oldMapVersion();
|
||||
|
||||
int32 oldSettingsVersion();
|
||||
|
||||
using TextWithTags = FlatTextarea::TextWithTags;
|
||||
struct MessageDraft {
|
||||
MessageDraft(MsgId msgId = 0, TextWithTags textWithTags = TextWithTags(), bool previewCancelled = false)
|
||||
: msgId(msgId)
|
||||
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "ui/buttons/peer_avatar_button.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
@ -58,6 +59,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "core/qthelp_url.h"
|
||||
#include "window/window_theme.h"
|
||||
#include "window/player_wrap_widget.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
StackItemSection::StackItemSection(std_::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
|
||||
, _memento(std_::move(memento)) {
|
||||
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "core/zlib_help.h"
|
||||
|
@ -78,11 +78,12 @@ public:
|
||||
void start(int framew, int frameh, int outerw, int outerh, ImageRoundRadius radius);
|
||||
QPixmap current(int framew, int frameh, int outerw, int outerh, uint64 ms);
|
||||
QPixmap frameOriginal() const {
|
||||
Frame *frame = frameToShow();
|
||||
if (!frame) return QPixmap();
|
||||
QPixmap result(frame ? QPixmap::fromImage(frame->original) : QPixmap());
|
||||
result.detach();
|
||||
return result;
|
||||
if (auto frame = frameToShow()) {
|
||||
auto result = QPixmap::fromImage(frame->original);
|
||||
result.detach();
|
||||
return result;
|
||||
}
|
||||
return QPixmap();
|
||||
}
|
||||
bool currentDisplayed() const {
|
||||
Frame *frame = frameToShow();
|
||||
|
@ -118,7 +118,7 @@ overviewLinksChecked: icon {
|
||||
{ "overview_links_check", #ffffff, point(4px, 5px) },
|
||||
};
|
||||
|
||||
overviewFilter: flatInput(inpDefGray) {
|
||||
overviewFilter: FlatInput(defaultFlatInput) {
|
||||
font: font(fsize);
|
||||
bgColor: #f2f2f2;
|
||||
phColor: #949494;
|
||||
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "window/top_bar_widget.h"
|
||||
#include "window/window_theme.h"
|
||||
#include "lang.h"
|
||||
@ -77,17 +78,17 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
||||
setMouseTracking(true);
|
||||
|
||||
connect(_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
|
||||
connect(&_search, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
||||
connect(&_search, SIGNAL(changed()), this, SLOT(onSearchUpdate()));
|
||||
connect(_search, SIGNAL(cancelled()), this, SLOT(onCancel()));
|
||||
connect(_search, SIGNAL(changed()), this, SLOT(onSearchUpdate()));
|
||||
|
||||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||
|
||||
_cancelSearch->hide();
|
||||
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||
_search.show();
|
||||
_search->show();
|
||||
} else {
|
||||
_search.hide();
|
||||
_search->hide();
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +177,7 @@ void OverviewInner::fixItemIndex(int32 ¤t, MsgId msgId) const {
|
||||
}
|
||||
|
||||
void OverviewInner::searchReceived(SearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req) {
|
||||
if (!_search.text().isEmpty()) {
|
||||
if (!_search->text().isEmpty()) {
|
||||
if (type == SearchFromStart) {
|
||||
SearchQueries::iterator i = _searchQueries.find(req);
|
||||
if (i != _searchQueries.cend()) {
|
||||
@ -683,7 +684,7 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
|
||||
|
||||
void OverviewInner::activate() {
|
||||
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||
_search.setFocus();
|
||||
_search->setFocus();
|
||||
} else {
|
||||
setFocus();
|
||||
}
|
||||
@ -1111,7 +1112,7 @@ void OverviewInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
}
|
||||
|
||||
void OverviewInner::keyPressEvent(QKeyEvent *e) {
|
||||
if ((_search.isHidden() || !_search.hasFocus()) && !_overview->isHidden() && e->key() == Qt::Key_Escape) {
|
||||
if ((_search->isHidden() || !_search->hasFocus()) && !_overview->isHidden() && e->key() == Qt::Key_Escape) {
|
||||
onCancel();
|
||||
} else if (e->key() == Qt::Key_Back) {
|
||||
App::main()->showBackFromStack();
|
||||
@ -1282,8 +1283,8 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
|
||||
}
|
||||
_rowsLeft = (_width - _rowWidth) / 2;
|
||||
|
||||
_search.setGeometry(_rowsLeft, st::linksSearchMargin.top(), _rowWidth, _search.height());
|
||||
_cancelSearch->moveToLeft(_rowsLeft + _rowWidth - _cancelSearch->width(), _search.y());
|
||||
_search->setGeometry(_rowsLeft, st::linksSearchMargin.top(), _rowWidth, _search->height());
|
||||
_cancelSearch->moveToLeft(_rowsLeft + _rowWidth - _cancelSearch->width(), _search->y());
|
||||
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
for (int32 i = 0, l = _items.size(); i < l; ++i) {
|
||||
@ -1334,14 +1335,14 @@ void OverviewInner::switchType(MediaOverviewType type) {
|
||||
_type = type;
|
||||
_reversed = (_type != OverviewLinks && _type != OverviewFiles);
|
||||
if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||
_search.show();
|
||||
_search->show();
|
||||
} else {
|
||||
_search.hide();
|
||||
_search->hide();
|
||||
}
|
||||
|
||||
if (!_search.getLastText().isEmpty()) {
|
||||
_search.setText(QString());
|
||||
_search.updatePlaceholder();
|
||||
if (!_search->getLastText().isEmpty()) {
|
||||
_search->setText(QString());
|
||||
_search->updatePlaceholder();
|
||||
onSearchUpdate();
|
||||
}
|
||||
_cancelSearch->hide();
|
||||
@ -1425,7 +1426,7 @@ void OverviewInner::saveContextFile() {
|
||||
|
||||
bool OverviewInner::onSearchMessages(bool searchCache) {
|
||||
_searchTimer.stop();
|
||||
QString q = _search.text().trimmed();
|
||||
QString q = _search->text().trimmed();
|
||||
if (q.isEmpty()) {
|
||||
if (_searchRequest) {
|
||||
_searchRequest = 0;
|
||||
@ -1462,7 +1463,7 @@ void OverviewInner::onNeedSearchMessages() {
|
||||
}
|
||||
|
||||
void OverviewInner::onSearchUpdate() {
|
||||
QString filterText = (_type == OverviewLinks || _type == OverviewFiles) ? _search.text().trimmed() : QString();
|
||||
QString filterText = (_type == OverviewLinks || _type == OverviewFiles) ? _search->text().trimmed() : QString();
|
||||
bool inSearch = !filterText.isEmpty(), changed = (inSearch != _inSearch);
|
||||
_inSearch = inSearch;
|
||||
|
||||
@ -1495,11 +1496,11 @@ void OverviewInner::onCancel() {
|
||||
}
|
||||
|
||||
bool OverviewInner::onCancelSearch() {
|
||||
if (_search.isHidden()) return false;
|
||||
bool clearing = !_search.text().isEmpty();
|
||||
if (_search->isHidden()) return false;
|
||||
bool clearing = !_search->text().isEmpty();
|
||||
_cancelSearch->hide();
|
||||
_search.clear();
|
||||
_search.updatePlaceholder();
|
||||
_search->clear();
|
||||
_search->updatePlaceholder();
|
||||
onSearchUpdate();
|
||||
return clearing;
|
||||
}
|
||||
@ -1796,7 +1797,7 @@ void OverviewInner::recountMargins() {
|
||||
_marginTop = st::playlistPadding;
|
||||
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
|
||||
} else if (_type == OverviewLinks || _type == OverviewFiles) {
|
||||
_marginTop = st::linksSearchMargin.top() + _search.height() + st::linksSearchMargin.bottom();
|
||||
_marginTop = st::linksSearchMargin.top() + _search->height() + st::linksSearchMargin.bottom();
|
||||
_marginBottom = qMax(_minHeight - _height - _marginTop, int32(st::playlistPadding));
|
||||
} else {
|
||||
_marginBottom = st::playlistPadding;
|
||||
|
@ -35,6 +35,7 @@ namespace Ui {
|
||||
class PlainShadow;
|
||||
class PopupMenu;
|
||||
class IconButton;
|
||||
class FlatInput;
|
||||
} // namespace Ui
|
||||
|
||||
class OverviewWidget;
|
||||
@ -179,7 +180,7 @@ private:
|
||||
Overview::Layout::AbstractItem *layoutPrepare(const QDate &date, bool month);
|
||||
int32 setLayoutItem(int32 index, Overview::Layout::AbstractItem *item, int32 top);
|
||||
|
||||
FlatInput _search;
|
||||
ChildWidget<Ui::FlatInput> _search;
|
||||
ChildWidget<Ui::IconButton> _cancelSearch;
|
||||
QVector<MsgId> _results;
|
||||
int32 _itemsToBeLoaded;
|
||||
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "application.h"
|
||||
#include "ui/text/text.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "window/slide_animation.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
namespace Ui {
|
||||
class FlatInput;
|
||||
class LinkButton;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
@ -55,7 +56,7 @@ private:
|
||||
anim::ivalue a_coordUnder, a_coordOver;
|
||||
anim::fvalue a_shadow;
|
||||
|
||||
ChildWidget<FlatInput> _passcode;
|
||||
ChildWidget<Ui::FlatInput> _passcode;
|
||||
ChildWidget<Ui::RoundButton> _submit;
|
||||
ChildWidget<Ui::LinkButton> _logout;
|
||||
QString _error;
|
||||
|
@ -436,7 +436,7 @@ void MainWindow::createGlobalMenu() {
|
||||
namespace {
|
||||
void _sendKeySequence(Qt::Key key, Qt::KeyboardModifiers modifiers = Qt::NoModifier) {
|
||||
QWidget *focused = QApplication::focusWidget();
|
||||
if (qobject_cast<QLineEdit*>(focused) || qobject_cast<FlatTextarea*>(focused) || qobject_cast<HistoryInner*>(focused)) {
|
||||
if (qobject_cast<QLineEdit*>(focused) || qobject_cast<QTextEdit*>(focused) || qobject_cast<HistoryInner*>(focused)) {
|
||||
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyPress, key, modifiers));
|
||||
QApplication::postEvent(focused, new QKeyEvent(QEvent::KeyRelease, key, modifiers));
|
||||
}
|
||||
@ -498,11 +498,11 @@ void MainWindow::psMacUpdateMenu() {
|
||||
canUndo = edit->isUndoAvailable();
|
||||
canRedo = edit->isRedoAvailable();
|
||||
canPaste = !Application::clipboard()->text().isEmpty();
|
||||
} else if (auto edit = qobject_cast<FlatTextarea*>(focused)) {
|
||||
} else if (auto edit = qobject_cast<QTextEdit*>(focused)) {
|
||||
canCut = canCopy = canDelete = edit->textCursor().hasSelection();
|
||||
canSelectAll = !edit->isEmpty();
|
||||
canUndo = edit->isUndoAvailable();
|
||||
canRedo = edit->isRedoAvailable();
|
||||
canSelectAll = !edit->document()->isEmpty();
|
||||
canUndo = edit->document()->isUndoAvailable();
|
||||
canRedo = edit->document()->isRedoAvailable();
|
||||
canPaste = !Application::clipboard()->text().isEmpty();
|
||||
} else if (auto list = qobject_cast<HistoryInner*>(focused)) {
|
||||
canCopy = list->canCopySelected();
|
||||
@ -534,7 +534,7 @@ bool MainWindow::psFilterNativeEvent(void *event) {
|
||||
bool MainWindow::eventFilter(QObject *obj, QEvent *evt) {
|
||||
QEvent::Type t = evt->type();
|
||||
if (t == QEvent::FocusIn || t == QEvent::FocusOut) {
|
||||
if (qobject_cast<QLineEdit*>(obj) || qobject_cast<FlatTextarea*>(obj) || qobject_cast<HistoryInner*>(obj)) {
|
||||
if (qobject_cast<QLineEdit*>(obj) || qobject_cast<QTextEdit*>(obj) || qobject_cast<HistoryInner*>(obj)) {
|
||||
psMacUpdateMenu();
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
using "basic.style";
|
||||
using "basic_types.style";
|
||||
|
||||
using "window/window.style";
|
||||
|
||||
profileBg: windowBg;
|
||||
|
||||
profileTopBarHeight: topBarHeight;
|
||||
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "profile/profile_actions_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/buttons/left_outline_button.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/report_box.h"
|
||||
|
@ -22,6 +22,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace style {
|
||||
struct OutlineButton;
|
||||
} // namespace style
|
||||
|
||||
namespace st {
|
||||
extern const style::OutlineButton &defaultLeftOutlineButton;
|
||||
} // namespace st
|
||||
|
||||
namespace Ui {
|
||||
class LeftOutlineButton;
|
||||
} // namespace Ui
|
||||
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
#include "styles/style_profile.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
|
@ -25,6 +25,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
class FlatLabel;
|
||||
|
||||
namespace style {
|
||||
struct RoundButton;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
class RoundButton;
|
||||
class LinkButton;
|
||||
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "observer_peer.h"
|
||||
#include "window/top_bar_widget.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
namespace Profile {
|
||||
|
||||
|
@ -129,7 +129,7 @@ void SettingsWidget::refreshManageAdminsButton() {
|
||||
};
|
||||
_manageAdmins.destroy();
|
||||
if (hasManageAdmins()) {
|
||||
_manageAdmins = new Ui::LeftOutlineButton(this, lang(lng_profile_manage_admins), st::defaultLeftOutlineButton);
|
||||
_manageAdmins.create(this, lang(lng_profile_manage_admins), st::defaultLeftOutlineButton);
|
||||
_manageAdmins->show();
|
||||
connect(_manageAdmins, SIGNAL(clicked()), this, SLOT(onManageAdmins()));
|
||||
}
|
||||
@ -152,7 +152,7 @@ void SettingsWidget::refreshInviteLinkButton() {
|
||||
if (inviteLinkText.isEmpty()) {
|
||||
_inviteLink.destroy();
|
||||
} else {
|
||||
_inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText, st::defaultLeftOutlineButton);
|
||||
_inviteLink.create(this, inviteLinkText, st::defaultLeftOutlineButton);
|
||||
_inviteLink->show();
|
||||
connect(_inviteLink, SIGNAL(clicked()), this, SLOT(onInviteLink()));
|
||||
}
|
||||
|
@ -70,8 +70,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "ui/animation.h"
|
||||
#include "ui/twidget.h"
|
||||
#include "ui/flatinput.h"
|
||||
#include "ui/flattextarea.h"
|
||||
#include "ui/scrollarea.h"
|
||||
#include "ui/images.h"
|
||||
#include "ui/text/text.h"
|
||||
|
@ -23,6 +23,13 @@ using "basic.style";
|
||||
using "boxes/boxes.style";
|
||||
using "ui/widgets/widgets.style";
|
||||
|
||||
switchPmButton: RoundButton(defaultBoxButton) {
|
||||
width: 320px;
|
||||
height: 34px;
|
||||
textTop: 7px;
|
||||
downTextTop: 8px;
|
||||
}
|
||||
|
||||
stickersTrendingHeader: 45px;
|
||||
stickersTrendingSkip: 15px;
|
||||
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "ui/abstract_button.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "ui/abstract_button.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
class PeerData;
|
||||
|
||||
|
@ -111,7 +111,7 @@ CountryInput::CountryInput(QWidget *parent, const style::countryInput &st) : QWi
|
||||
}
|
||||
_arrow = App::pixmapFromImageInPlace(std_::move(trImage));
|
||||
_inner = QRect(0, 0, _st.width, _st.height);
|
||||
_arrowRect = QRect((st::inpIntroCountryCode.width - _arrow.width() - 1) / 2, _st.height, _arrow.width(), _arrow.height());
|
||||
_arrowRect = QRect((st::introCountryCode.width - _arrow.width() - 1) / 2, _st.height, _arrow.width(), _arrow.height());
|
||||
}
|
||||
|
||||
void CountryInput::paintEvent(QPaintEvent *e) {
|
||||
|
@ -20,7 +20,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/flatinput.h"
|
||||
#include "ui/scrollarea.h"
|
||||
#include "ui/effects/rect_shadow.h"
|
||||
#include "boxes/abstractbox.h"
|
||||
|
@ -229,7 +229,7 @@ void RoundShadowAnimation::paintShadowHorizontal(int left, int right, int top, c
|
||||
|
||||
void PanelAnimation::setFinalImage(QImage &&finalImage, QRect inner) {
|
||||
t_assert(!started());
|
||||
_finalImage = QPixmap::fromImage(std_::move(finalImage).convertToFormat(QImage::Format_ARGB32_Premultiplied), Qt::ColorOnly);
|
||||
_finalImage = App::pixmapFromImageInPlace(std_::move(finalImage).convertToFormat(QImage::Format_ARGB32_Premultiplied));
|
||||
|
||||
t_assert(!_finalImage.isNull());
|
||||
_finalWidth = _finalImage.width();
|
||||
@ -317,7 +317,7 @@ void PanelAnimation::createFadeMask() {
|
||||
}
|
||||
ints += intsPerLineAdded;
|
||||
}
|
||||
_fadeMask = QPixmap::fromImage(style::colorizeImage(result, _st.fadeBg), Qt::ColorOnly);
|
||||
_fadeMask = App::pixmapFromImageInPlace(style::colorizeImage(result, _st.fadeBg));
|
||||
_fadeHeight = _fadeMask.height();
|
||||
}
|
||||
|
||||
|
157
Telegram/SourceFiles/ui/effects/ripple_animation.cpp
Normal file
157
Telegram/SourceFiles/ui/effects/ripple_animation.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
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 "ui/effects/ripple_animation.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class RippleAnimation::Ripple {
|
||||
public:
|
||||
Ripple(const style::RippleAnimation &st, QPoint origin, int startRadius, const QPixmap &mask, UpdateCallback update);
|
||||
|
||||
void paint(QPainter &p, const QPixmap &mask, uint64 ms);
|
||||
|
||||
void stop();
|
||||
bool finished() const {
|
||||
return _hiding && !_hide.animating();
|
||||
}
|
||||
|
||||
private:
|
||||
const style::RippleAnimation &_st;
|
||||
UpdateCallback _update;
|
||||
|
||||
QPoint _origin;
|
||||
int _radiusFrom = 0;
|
||||
int _radiusTo = 0;
|
||||
|
||||
bool _hiding = false;
|
||||
FloatAnimation _show;
|
||||
FloatAnimation _hide;
|
||||
QPixmap _cache;
|
||||
QImage _frame;
|
||||
|
||||
};
|
||||
|
||||
RippleAnimation::Ripple::Ripple(const style::RippleAnimation &st, QPoint origin, int startRadius, const QPixmap &mask, UpdateCallback update)
|
||||
: _st(st)
|
||||
, _update(update)
|
||||
, _origin(origin)
|
||||
, _radiusFrom(startRadius)
|
||||
, _frame(mask.size(), QImage::Format_ARGB32_Premultiplied) {
|
||||
_frame.setDevicePixelRatio(mask.devicePixelRatio());
|
||||
|
||||
QPoint points[] = {
|
||||
{ 0, 0 },
|
||||
{ _frame.width() / cIntRetinaFactor(), 0 },
|
||||
{ _frame.width() / cIntRetinaFactor(), _frame.height() / cIntRetinaFactor() },
|
||||
{ 0, _frame.height() / cIntRetinaFactor() },
|
||||
};
|
||||
for (auto point : points) {
|
||||
accumulate_max(_radiusTo, style::point::dotProduct(_origin - point, _origin - point));
|
||||
}
|
||||
_radiusTo = qRound(sqrt(_radiusTo));
|
||||
|
||||
_show.start(UpdateCallback(_update), 0., 1., _st.showDuration);
|
||||
}
|
||||
|
||||
void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, uint64 ms) {
|
||||
auto opacity = _hide.current(ms, _hiding ? 0. : 1.);
|
||||
if (opacity == 0.) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cache.isNull()) {
|
||||
auto radius = anim::interpolate(_radiusFrom, _radiusTo, _show.current(ms, 1.));
|
||||
_frame.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&_frame);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(_st.color);
|
||||
p.drawEllipse(_origin, radius, radius);
|
||||
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.drawPixmap(0, 0, mask);
|
||||
}
|
||||
if (radius == _radiusTo) {
|
||||
_cache = App::pixmapFromImageInPlace(std_::move(_frame));
|
||||
}
|
||||
}
|
||||
auto saved = p.opacity();
|
||||
if (opacity != 1.) p.setOpacity(saved * opacity);
|
||||
if (_cache.isNull()) {
|
||||
p.drawImage(0, 0, _frame);
|
||||
} else {
|
||||
p.drawPixmap(0, 0, _cache);
|
||||
}
|
||||
if (opacity != 1.) p.setOpacity(saved);
|
||||
}
|
||||
|
||||
void RippleAnimation::Ripple::stop() {
|
||||
_hiding = true;
|
||||
_hide.start(UpdateCallback(_update), 1., 0., _st.hideDuration);
|
||||
}
|
||||
|
||||
RippleAnimation::RippleAnimation(const style::RippleAnimation &st, QImage mask, UpdateCallback callback)
|
||||
: _st(st)
|
||||
, _mask(App::pixmapFromImageInPlace(std_::move(mask)))
|
||||
, _update(std_::move(callback)) {
|
||||
}
|
||||
|
||||
|
||||
void RippleAnimation::add(QPoint origin, int startRadius) {
|
||||
_ripples.push_back(new Ripple(_st, origin, startRadius, _mask, _update));
|
||||
}
|
||||
|
||||
void RippleAnimation::stopLast() {
|
||||
if (!_ripples.isEmpty()) {
|
||||
_ripples.back()->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, uint64 ms) {
|
||||
if (_ripples.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rtl()) x = outerWidth - x - (_mask.width() / cIntRetinaFactor());
|
||||
p.translate(x, y);
|
||||
for (auto ripple : _ripples) {
|
||||
ripple->paint(p, _mask, ms);
|
||||
}
|
||||
p.translate(-x, -y);
|
||||
clearFinished();
|
||||
}
|
||||
|
||||
void RippleAnimation::clearFinished() {
|
||||
while (!_ripples.isEmpty() && _ripples.front()->finished()) {
|
||||
delete base::take(_ripples.front());
|
||||
_ripples.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void RippleAnimation::clear() {
|
||||
for (auto ripple : base::take(_ripples)) {
|
||||
delete ripple;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
62
Telegram/SourceFiles/ui/effects/ripple_animation.h
Normal file
62
Telegram/SourceFiles/ui/effects/ripple_animation.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class RippleAnimation {
|
||||
public:
|
||||
using UpdateCallback = base::lambda_wrap<void()>;
|
||||
|
||||
// White upon transparent mask, like colorizeImage(black-white-mask, white).
|
||||
RippleAnimation(const style::RippleAnimation &st, QImage mask, UpdateCallback update);
|
||||
|
||||
void setMask(QImage &&mask);
|
||||
|
||||
void add(QPoint origin, int startRadius = 0);
|
||||
void stopLast();
|
||||
|
||||
void paint(QPainter &p, int x, int y, int outerWidth, uint64 ms);
|
||||
|
||||
bool empty() const {
|
||||
return _ripples.isEmpty();
|
||||
}
|
||||
|
||||
~RippleAnimation() {
|
||||
clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void clear();
|
||||
void clearFinished();
|
||||
|
||||
const style::RippleAnimation &_st;
|
||||
QPixmap _mask;
|
||||
UpdateCallback _update;
|
||||
|
||||
class Ripple;
|
||||
QList<Ripple*> _ripples;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
File diff suppressed because it is too large
Load Diff
@ -1,261 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
#include "animation.h"
|
||||
|
||||
class UserData;
|
||||
static UserData * const LookingUpInlineBot = SharedMemoryLocation<UserData, 0>();
|
||||
|
||||
class FlatTextarea : public QTextEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
|
||||
public:
|
||||
struct Tag {
|
||||
int offset, length;
|
||||
QString id;
|
||||
};
|
||||
using TagList = QVector<Tag>;
|
||||
struct TextWithTags {
|
||||
using Tags = FlatTextarea::TagList;
|
||||
QString text;
|
||||
Tags tags;
|
||||
};
|
||||
|
||||
static QByteArray serializeTagsList(const TagList &tags);
|
||||
static TagList deserializeTagsList(QByteArray data, int textLength);
|
||||
static QString tagsMimeType();
|
||||
|
||||
FlatTextarea(QWidget *parent, const style::flatTextarea &st, const QString &ph = QString(), const QString &val = QString(), const TagList &tags = TagList());
|
||||
|
||||
void setMaxLength(int32 maxLength);
|
||||
void setMinHeight(int32 minHeight);
|
||||
void setMaxHeight(int32 maxHeight);
|
||||
|
||||
void setPlaceholder(const QString &ph, int32 afterSymbols = 0);
|
||||
void updatePlaceholder();
|
||||
void finishPlaceholder();
|
||||
|
||||
QRect getTextRect() const;
|
||||
int32 fakeMargin() const;
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
EmojiPtr getSingleEmoji() const;
|
||||
QString getMentionHashtagBotCommandPart(bool &start) const;
|
||||
|
||||
// Get the current inline bot and request string for it.
|
||||
// The *outInlineBot can be filled by LookingUpInlineBot shared ptr.
|
||||
// In that case the caller should lookup the bot by *outInlineBotUsername.
|
||||
QString getInlineBotQuery(UserData **outInlineBot, QString *outInlineBotUsername) const;
|
||||
|
||||
void removeSingleEmoji();
|
||||
bool hasText() const;
|
||||
|
||||
bool isUndoAvailable() const;
|
||||
bool isRedoAvailable() const;
|
||||
|
||||
void parseLinks();
|
||||
QStringList linksList() const;
|
||||
|
||||
void insertFromMimeData(const QMimeData *source) override;
|
||||
|
||||
QMimeData *createMimeDataFromSelection() const override;
|
||||
|
||||
enum class SubmitSettings {
|
||||
None,
|
||||
Enter,
|
||||
CtrlEnter,
|
||||
Both,
|
||||
};
|
||||
void setSubmitSettings(SubmitSettings settings);
|
||||
|
||||
const TextWithTags &getTextWithTags() const {
|
||||
return _lastTextWithTags;
|
||||
}
|
||||
TextWithTags getTextWithTagsPart(int start, int end = -1);
|
||||
void insertTag(const QString &text, QString tagId = QString());
|
||||
|
||||
bool isEmpty() const {
|
||||
return _lastTextWithTags.text.isEmpty();
|
||||
}
|
||||
|
||||
enum UndoHistoryAction {
|
||||
AddToUndoHistory,
|
||||
MergeWithUndoHistory,
|
||||
ClearUndoHistory
|
||||
};
|
||||
void setTextWithTags(const TextWithTags &textWithTags, UndoHistoryAction undoHistoryAction = AddToUndoHistory);
|
||||
|
||||
// If you need to make some preparations of tags before putting them to QMimeData
|
||||
// (and then to clipboard or to drag-n-drop object), here is a strategy for that.
|
||||
class TagMimeProcessor {
|
||||
public:
|
||||
virtual QString mimeTagFromTag(const QString &tagId) = 0;
|
||||
virtual QString tagFromMimeTag(const QString &mimeTag) = 0;
|
||||
virtual ~TagMimeProcessor() {
|
||||
}
|
||||
};
|
||||
void setTagMimeProcessor(std_::unique_ptr<TagMimeProcessor> &&processor);
|
||||
|
||||
public slots:
|
||||
void onTouchTimer();
|
||||
|
||||
void onDocumentContentsChange(int position, int charsRemoved, int charsAdded);
|
||||
void onDocumentContentsChanged();
|
||||
|
||||
void onUndoAvailable(bool avail);
|
||||
void onRedoAvailable(bool avail);
|
||||
|
||||
signals:
|
||||
void resized();
|
||||
void changed();
|
||||
void submitted(bool ctrlShiftEnter);
|
||||
void cancelled();
|
||||
void tabbed();
|
||||
void spacedReturnedPasted();
|
||||
void linksChanged();
|
||||
|
||||
protected:
|
||||
void enterEventHook(QEvent *e) {
|
||||
return QTextEdit::enterEvent(e);
|
||||
}
|
||||
void leaveEventHook(QEvent *e) {
|
||||
return QTextEdit::leaveEvent(e);
|
||||
}
|
||||
|
||||
bool viewportEvent(QEvent *e) override;
|
||||
void touchEvent(QTouchEvent *e);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void focusInEvent(QFocusEvent *e) override;
|
||||
void focusOutEvent(QFocusEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void dropEvent(QDropEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
virtual void correctValue(const QString &was, QString &now, TagList &nowTags) {
|
||||
}
|
||||
|
||||
void insertEmoji(EmojiPtr emoji, QTextCursor c);
|
||||
|
||||
QVariant loadResource(int type, const QUrl &name) override;
|
||||
|
||||
void checkContentHeight();
|
||||
|
||||
private:
|
||||
// "start" and "end" are in coordinates of text where emoji are replaced
|
||||
// by ObjectReplacementCharacter. If "end" = -1 means get text till the end.
|
||||
QString getTextPart(int start, int end, TagList *outTagsList, bool *outTagsChanged = nullptr) const;
|
||||
|
||||
void getSingleEmojiFragment(QString &text, QTextFragment &fragment) const;
|
||||
|
||||
// After any characters added we must postprocess them. This includes:
|
||||
// 1. Replacing font family to semibold for ~ characters, if we used Open Sans 13px.
|
||||
// 2. Replacing font family from semibold for all non-~ characters, if we used ...
|
||||
// 3. Replacing emoji code sequences by ObjectReplacementCharacters with emoji pics.
|
||||
// 4. Interrupting tags in which the text was inserted by any char except a letter.
|
||||
// 5. Applying tags from "_insertedTags" in case we pasted text with tags, not just text.
|
||||
// Rule 4 applies only if we inserted chars not in the middle of a tag (but at the end).
|
||||
void processFormatting(int changedPosition, int changedEnd);
|
||||
|
||||
bool heightAutoupdated();
|
||||
|
||||
int placeholderSkipWidth() const;
|
||||
|
||||
int _minHeight = -1; // < 0 - no autosize
|
||||
int _maxHeight = -1;
|
||||
int _maxLength = -1;
|
||||
SubmitSettings _submitSettings = SubmitSettings::Enter;
|
||||
|
||||
QString _ph, _phelided;
|
||||
int _phAfter = 0;
|
||||
bool _phVisible;
|
||||
anim::ivalue a_phLeft;
|
||||
anim::fvalue a_phAlpha;
|
||||
anim::fvalue a_phColorFocused;
|
||||
Animation _a_appearance;
|
||||
|
||||
TextWithTags _lastTextWithTags;
|
||||
|
||||
// Tags list which we should apply while setText() call or insert from mime data.
|
||||
TagList _insertedTags;
|
||||
bool _insertedTagsAreFromMime;
|
||||
|
||||
// Override insert position and charsAdded from complex text editing
|
||||
// (like drag-n-drop in the same text edit field).
|
||||
int _realInsertPosition = -1;
|
||||
int _realCharsAdded = 0;
|
||||
|
||||
std_::unique_ptr<TagMimeProcessor> _tagMimeProcessor;
|
||||
|
||||
const style::flatTextarea &_st;
|
||||
|
||||
bool _undoAvailable = false;
|
||||
bool _redoAvailable = false;
|
||||
bool _inDrop = false;
|
||||
bool _inHeightCheck = false;
|
||||
|
||||
int _fakeMargin = 0;
|
||||
|
||||
QTimer _touchTimer;
|
||||
bool _touchPress = false;
|
||||
bool _touchRightButton = false;
|
||||
bool _touchMove = false;
|
||||
QPoint _touchStart;
|
||||
|
||||
bool _correcting = false;
|
||||
|
||||
struct LinkRange {
|
||||
int start;
|
||||
int length;
|
||||
};
|
||||
friend bool operator==(const LinkRange &a, const LinkRange &b);
|
||||
friend bool operator!=(const LinkRange &a, const LinkRange &b);
|
||||
using LinkRanges = QVector<LinkRange>;
|
||||
LinkRanges _links;
|
||||
};
|
||||
|
||||
inline bool operator==(const FlatTextarea::Tag &a, const FlatTextarea::Tag &b) {
|
||||
return (a.offset == b.offset) && (a.length == b.length) && (a.id == b.id);
|
||||
}
|
||||
inline bool operator!=(const FlatTextarea::Tag &a, const FlatTextarea::Tag &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator==(const FlatTextarea::TextWithTags &a, const FlatTextarea::TextWithTags &b) {
|
||||
return (a.text == b.text) && (a.tags == b.tags);
|
||||
}
|
||||
inline bool operator!=(const FlatTextarea::TextWithTags &a, const FlatTextarea::TextWithTags &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator==(const FlatTextarea::LinkRange &a, const FlatTextarea::LinkRange &b) {
|
||||
return (a.start == b.start) && (a.length == b.length);
|
||||
}
|
||||
inline bool operator!=(const FlatTextarea::LinkRange &a, const FlatTextarea::LinkRange &b) {
|
||||
return !(a == b);
|
||||
}
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
FlatButton::FlatButton(QWidget *parent, const QString &text, const style::FlatButton &st) : AbstractButton(parent)
|
||||
@ -87,6 +89,27 @@ void FlatButton::onStateChanged(int oldState, StateChangeSource source) {
|
||||
} else {
|
||||
_a_appearance.start();
|
||||
}
|
||||
|
||||
handleRipples(oldState & StateDown, (source == StateChangeSource::ByPress));
|
||||
}
|
||||
|
||||
void FlatButton::handleRipples(bool wasDown, bool wasPress) {
|
||||
auto down = static_cast<bool>(_state & StateDown);
|
||||
if (!_st.ripple.showDuration || down == wasDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (down && wasPress) {
|
||||
// Start a ripple only from mouse press.
|
||||
if (!_ripple) {
|
||||
_ripple = std_::make_unique<Ui::RippleAnimation>(_st.ripple, prepareRippleMask(), [this] { update(); });
|
||||
}
|
||||
auto clickPosition = mapFromGlobal(QCursor::pos());
|
||||
_ripple->add(clickPosition);
|
||||
} else if (!down && _ripple) {
|
||||
// Finish ripple anyway.
|
||||
_ripple->stopLast();
|
||||
}
|
||||
}
|
||||
|
||||
void FlatButton::paintEvent(QPaintEvent *e) {
|
||||
@ -97,6 +120,14 @@ void FlatButton::paintEvent(QPaintEvent *e) {
|
||||
p.setOpacity(_opacity);
|
||||
p.fillRect(r, anim::brush(_st.bgColor, _st.overBgColor, a_over.current()));
|
||||
|
||||
auto ms = getms();
|
||||
if (_ripple) {
|
||||
_ripple->paint(p, 0, 0, width(), ms);
|
||||
if (_ripple->empty()) {
|
||||
_ripple.reset();
|
||||
}
|
||||
}
|
||||
|
||||
p.setFont((_state & StateOver) ? _st.overFont : _st.font);
|
||||
p.setRenderHint(QPainter::TextAntialiasing);
|
||||
p.setPen(anim::pen(_st.color, _st.overColor, a_over.current()));
|
||||
@ -107,6 +138,15 @@ void FlatButton::paintEvent(QPaintEvent *e) {
|
||||
p.drawText(r, _text, style::al_top);
|
||||
}
|
||||
|
||||
QImage FlatButton::prepareRippleMask() const {
|
||||
auto result = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(cRetinaFactor());
|
||||
result.fill(QColor(255, 255, 255));
|
||||
return std_::move(result);
|
||||
}
|
||||
|
||||
FlatButton::~FlatButton() = default;
|
||||
|
||||
LinkButton::LinkButton(QWidget *parent, const QString &text, const style::LinkButton &st) : AbstractButton(parent)
|
||||
, _text(text)
|
||||
, _textWidth(st.font->width(_text))
|
||||
@ -210,16 +250,25 @@ int RoundButton::contentWidth() const {
|
||||
void RoundButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
int innerWidth = contentWidth();
|
||||
auto rounded = rtlrect(rect().marginsRemoved(_st.padding), width());
|
||||
auto innerWidth = contentWidth();
|
||||
auto rounded = rect().marginsRemoved(_st.padding);
|
||||
if (_fullWidthOverride < 0) {
|
||||
rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height());
|
||||
}
|
||||
App::roundRect(p, rounded, _st.textBg, ImageRoundRadius::Small);
|
||||
App::roundRect(p, myrtlrect(rounded), _st.textBg, ImageRoundRadius::Small);
|
||||
|
||||
auto over = (_state & StateOver);
|
||||
auto down = (_state & StateDown);
|
||||
if (over) {
|
||||
App::roundRect(p, rounded, _st.textBgOver, ImageRoundRadius::Small);
|
||||
App::roundRect(p, myrtlrect(rounded), _st.textBgOver, ImageRoundRadius::Small);
|
||||
}
|
||||
|
||||
auto ms = getms();
|
||||
if (_ripple) {
|
||||
_ripple->paint(p, rounded.x(), rounded.y(), width(), ms);
|
||||
if (_ripple->empty()) {
|
||||
_ripple.reset();
|
||||
}
|
||||
}
|
||||
|
||||
p.setFont(_st.font);
|
||||
@ -230,12 +279,12 @@ void RoundButton::paintEvent(QPaintEvent *e) {
|
||||
int textTopDelta = (_state & StateDown) ? (_st.downTextTop - _st.textTop) : 0;
|
||||
int textTop = _st.padding.top() + _st.textTop + textTopDelta;
|
||||
if (!_text.isEmpty()) {
|
||||
p.setPen(over ? _st.textFgOver : _st.textFg);
|
||||
p.setPen((over || down) ? _st.textFgOver : _st.textFg);
|
||||
p.drawTextLeft(textLeft, textTop, width(), _text);
|
||||
}
|
||||
if (!_secondaryText.isEmpty()) {
|
||||
textLeft += _textWidth + (_textWidth ? _st.secondarySkip : 0);
|
||||
p.setPen(over ? _st.secondaryTextFgOver : _st.secondaryTextFg);
|
||||
p.setPen((over || down) ? _st.secondaryTextFgOver : _st.secondaryTextFg);
|
||||
p.drawTextLeft(textLeft, textTop, width(), _secondaryText);
|
||||
}
|
||||
_st.icon.paint(p, QPoint(_st.padding.left(), _st.padding.right() + textTopDelta), width());
|
||||
@ -243,8 +292,50 @@ void RoundButton::paintEvent(QPaintEvent *e) {
|
||||
|
||||
void RoundButton::onStateChanged(int oldState, StateChangeSource source) {
|
||||
update();
|
||||
|
||||
handleRipples(oldState & StateDown, (source == StateChangeSource::ByPress));
|
||||
}
|
||||
|
||||
void RoundButton::handleRipples(bool wasDown, bool wasPress) {
|
||||
auto down = static_cast<bool>(_state & StateDown);
|
||||
if (!_st.ripple.showDuration || down == wasDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (down && wasPress) {
|
||||
// Start a ripple only from mouse press.
|
||||
if (!_ripple) {
|
||||
_ripple = std_::make_unique<Ui::RippleAnimation>(_st.ripple, prepareRippleMask(), [this] { update(); });
|
||||
}
|
||||
auto clickPosition = mapFromGlobal(QCursor::pos()) - QPoint(_st.padding.left(), _st.padding.top());
|
||||
_ripple->add(clickPosition);
|
||||
} else if (!down && _ripple) {
|
||||
// Finish ripple anyway.
|
||||
_ripple->stopLast();
|
||||
}
|
||||
}
|
||||
|
||||
QImage RoundButton::prepareRippleMask() const {
|
||||
auto innerWidth = contentWidth();
|
||||
auto rounded = rtlrect(rect().marginsRemoved(_st.padding), width());
|
||||
if (_fullWidthOverride < 0) {
|
||||
rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height());
|
||||
}
|
||||
|
||||
auto result = QImage(rounded.size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(cRetinaFactor());
|
||||
result.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&result);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(QColor(255, 255, 255));
|
||||
p.drawRoundedRect(rounded.translated(-rounded.topLeft()), st::buttonRadius, st::buttonRadius);
|
||||
}
|
||||
return std_::move(result);
|
||||
}
|
||||
|
||||
RoundButton::~RoundButton() = default;
|
||||
|
||||
IconButton::IconButton(QWidget *parent, const style::IconButton &st) : AbstractButton(parent)
|
||||
, _st(st) {
|
||||
resize(_st.width, _st.height);
|
||||
@ -260,6 +351,15 @@ void IconButton::setIcon(const style::icon *icon, const style::icon *iconOver) {
|
||||
void IconButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto ms = getms();
|
||||
|
||||
if (_ripple) {
|
||||
_ripple->paint(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), width(), ms);
|
||||
if (_ripple->empty()) {
|
||||
_ripple.reset();
|
||||
}
|
||||
}
|
||||
|
||||
auto over = _a_over.current(getms(), (_state & StateOver) ? 1. : 0.);
|
||||
auto overIcon = [this] {
|
||||
if (_iconOverrideOver) {
|
||||
@ -306,6 +406,50 @@ void IconButton::onStateChanged(int oldState, StateChangeSource source) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
handleRipples(oldState & StateDown, (source == StateChangeSource::ByPress));
|
||||
}
|
||||
|
||||
void IconButton::handleRipples(bool wasDown, bool wasPress) {
|
||||
auto down = static_cast<bool>(_state & StateDown);
|
||||
if (!_st.ripple.showDuration || _st.rippleAreaSize <= 0 || down == wasDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (down && wasPress) {
|
||||
// Start a ripple only from mouse press.
|
||||
if (!_ripple) {
|
||||
_ripple = std_::make_unique<Ui::RippleAnimation>(_st.ripple, prepareRippleMask(), [this] { update(); });
|
||||
}
|
||||
auto clickPosition = mapFromGlobal(QCursor::pos());
|
||||
auto rippleCenter = QRect(_st.rippleAreaPosition, QSize(_st.rippleAreaSize, _st.rippleAreaSize)).center();
|
||||
auto clickRadiusSquare = style::point::dotProduct(clickPosition - rippleCenter, clickPosition - rippleCenter);
|
||||
auto startRadius = 0;
|
||||
if (clickRadiusSquare * 4 > _st.rippleAreaSize * _st.rippleAreaSize) {
|
||||
startRadius = sqrt(clickRadiusSquare) - (_st.rippleAreaSize / 2);
|
||||
}
|
||||
_ripple->add(clickPosition - _st.rippleAreaPosition, startRadius);
|
||||
} else if (!down && _ripple) {
|
||||
// Finish ripple anyway.
|
||||
_ripple->stopLast();
|
||||
}
|
||||
}
|
||||
|
||||
QImage IconButton::prepareRippleMask() const {
|
||||
auto size = _st.rippleAreaSize * cIntRetinaFactor();
|
||||
auto result = QImage(size, size, QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(cRetinaFactor());
|
||||
result.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&result);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(QColor(255, 255, 255));
|
||||
p.drawEllipse(0, 0, _st.rippleAreaSize, _st.rippleAreaSize);
|
||||
}
|
||||
return std_::move(result);
|
||||
}
|
||||
|
||||
IconButton::~IconButton() = default;
|
||||
|
||||
} // namespace Ui
|
||||
|
@ -25,6 +25,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class RippleAnimation;
|
||||
|
||||
class FlatButton : public AbstractButton {
|
||||
public:
|
||||
FlatButton(QWidget *parent, const QString &text, const style::FlatButton &st);
|
||||
@ -38,12 +40,17 @@ public:
|
||||
|
||||
int32 textWidth() const;
|
||||
|
||||
~FlatButton();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
||||
|
||||
private:
|
||||
QImage prepareRippleMask() const;
|
||||
void handleRipples(bool wasDown, bool wasPress);
|
||||
|
||||
QString _text, _textForAutoSize;
|
||||
int _width;
|
||||
|
||||
@ -54,6 +61,8 @@ private:
|
||||
|
||||
float64 _opacity = 1.;
|
||||
|
||||
std_::unique_ptr<RippleAnimation> _ripple;
|
||||
|
||||
};
|
||||
|
||||
class LinkButton : public AbstractButton {
|
||||
@ -93,12 +102,17 @@ public:
|
||||
};
|
||||
void setTextTransform(TextTransform transform);
|
||||
|
||||
~RoundButton();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
||||
|
||||
private:
|
||||
QImage prepareRippleMask() const;
|
||||
void handleRipples(bool wasDown, bool wasPress);
|
||||
|
||||
void updateText();
|
||||
void resizeToText();
|
||||
|
||||
@ -114,6 +128,8 @@ private:
|
||||
|
||||
TextTransform _transform = TextTransform::ToUpper;
|
||||
|
||||
std_::unique_ptr<RippleAnimation> _ripple;
|
||||
|
||||
};
|
||||
|
||||
class IconButton : public AbstractButton {
|
||||
@ -123,18 +139,25 @@ public:
|
||||
// Pass nullptr to restore the default icon.
|
||||
void setIcon(const style::icon *icon, const style::icon *iconOver = nullptr);
|
||||
|
||||
~IconButton();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
||||
|
||||
private:
|
||||
QImage prepareRippleMask() const;
|
||||
void handleRipples(bool wasDown, bool wasPress);
|
||||
|
||||
const style::IconButton &_st;
|
||||
const style::icon *_iconOverride = nullptr;
|
||||
const style::icon *_iconOverrideOver = nullptr;
|
||||
|
||||
FloatAnimation _a_over;
|
||||
|
||||
std_::unique_ptr<RippleAnimation> _ripple;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "ui/abstract_button.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,14 +20,232 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "animation.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
class UserData;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
static UserData * const LookingUpInlineBot = SharedMemoryLocation<UserData, 0>();
|
||||
|
||||
class FlatTextarea : public QTextEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
|
||||
public:
|
||||
using TagList = TextWithTags::Tags;
|
||||
|
||||
static QByteArray serializeTagsList(const TagList &tags);
|
||||
static TagList deserializeTagsList(QByteArray data, int textLength);
|
||||
static QString tagsMimeType();
|
||||
|
||||
FlatTextarea(QWidget *parent, const style::FlatTextarea &st, const QString &ph = QString(), const QString &val = QString(), const TagList &tags = TagList());
|
||||
|
||||
void setMaxLength(int32 maxLength);
|
||||
void setMinHeight(int32 minHeight);
|
||||
void setMaxHeight(int32 maxHeight);
|
||||
|
||||
void setPlaceholder(const QString &ph, int32 afterSymbols = 0);
|
||||
void updatePlaceholder();
|
||||
void finishPlaceholder();
|
||||
|
||||
QRect getTextRect() const;
|
||||
int32 fakeMargin() const;
|
||||
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
EmojiPtr getSingleEmoji() const;
|
||||
QString getMentionHashtagBotCommandPart(bool &start) const;
|
||||
|
||||
// Get the current inline bot and request string for it.
|
||||
// The *outInlineBot can be filled by LookingUpInlineBot shared ptr.
|
||||
// In that case the caller should lookup the bot by *outInlineBotUsername.
|
||||
QString getInlineBotQuery(UserData **outInlineBot, QString *outInlineBotUsername) const;
|
||||
|
||||
void removeSingleEmoji();
|
||||
bool hasText() const;
|
||||
|
||||
bool isUndoAvailable() const;
|
||||
bool isRedoAvailable() const;
|
||||
|
||||
void parseLinks();
|
||||
QStringList linksList() const;
|
||||
|
||||
void insertFromMimeData(const QMimeData *source) override;
|
||||
|
||||
QMimeData *createMimeDataFromSelection() const override;
|
||||
|
||||
enum class SubmitSettings {
|
||||
None,
|
||||
Enter,
|
||||
CtrlEnter,
|
||||
Both,
|
||||
};
|
||||
void setSubmitSettings(SubmitSettings settings);
|
||||
|
||||
const TextWithTags &getTextWithTags() const {
|
||||
return _lastTextWithTags;
|
||||
}
|
||||
TextWithTags getTextWithTagsPart(int start, int end = -1);
|
||||
void insertTag(const QString &text, QString tagId = QString());
|
||||
|
||||
bool isEmpty() const {
|
||||
return _lastTextWithTags.text.isEmpty();
|
||||
}
|
||||
|
||||
enum UndoHistoryAction {
|
||||
AddToUndoHistory,
|
||||
MergeWithUndoHistory,
|
||||
ClearUndoHistory
|
||||
};
|
||||
void setTextWithTags(const TextWithTags &textWithTags, UndoHistoryAction undoHistoryAction = AddToUndoHistory);
|
||||
|
||||
// If you need to make some preparations of tags before putting them to QMimeData
|
||||
// (and then to clipboard or to drag-n-drop object), here is a strategy for that.
|
||||
class TagMimeProcessor {
|
||||
public:
|
||||
virtual QString mimeTagFromTag(const QString &tagId) = 0;
|
||||
virtual QString tagFromMimeTag(const QString &mimeTag) = 0;
|
||||
virtual ~TagMimeProcessor() {
|
||||
}
|
||||
};
|
||||
void setTagMimeProcessor(std_::unique_ptr<TagMimeProcessor> &&processor);
|
||||
|
||||
public slots:
|
||||
void onTouchTimer();
|
||||
|
||||
void onDocumentContentsChange(int position, int charsRemoved, int charsAdded);
|
||||
void onDocumentContentsChanged();
|
||||
|
||||
void onUndoAvailable(bool avail);
|
||||
void onRedoAvailable(bool avail);
|
||||
|
||||
signals:
|
||||
void resized();
|
||||
void changed();
|
||||
void submitted(bool ctrlShiftEnter);
|
||||
void cancelled();
|
||||
void tabbed();
|
||||
void spacedReturnedPasted();
|
||||
void linksChanged();
|
||||
|
||||
protected:
|
||||
void enterEventHook(QEvent *e) {
|
||||
return QTextEdit::enterEvent(e);
|
||||
}
|
||||
void leaveEventHook(QEvent *e) {
|
||||
return QTextEdit::leaveEvent(e);
|
||||
}
|
||||
|
||||
bool viewportEvent(QEvent *e) override;
|
||||
void touchEvent(QTouchEvent *e);
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void focusInEvent(QFocusEvent *e) override;
|
||||
void focusOutEvent(QFocusEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void dropEvent(QDropEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
virtual void correctValue(const QString &was, QString &now, TagList &nowTags) {
|
||||
}
|
||||
|
||||
void insertEmoji(EmojiPtr emoji, QTextCursor c);
|
||||
|
||||
QVariant loadResource(int type, const QUrl &name) override;
|
||||
|
||||
void checkContentHeight();
|
||||
|
||||
private:
|
||||
// "start" and "end" are in coordinates of text where emoji are replaced
|
||||
// by ObjectReplacementCharacter. If "end" = -1 means get text till the end.
|
||||
QString getTextPart(int start, int end, TagList *outTagsList, bool *outTagsChanged = nullptr) const;
|
||||
|
||||
void getSingleEmojiFragment(QString &text, QTextFragment &fragment) const;
|
||||
|
||||
// After any characters added we must postprocess them. This includes:
|
||||
// 1. Replacing font family to semibold for ~ characters, if we used Open Sans 13px.
|
||||
// 2. Replacing font family from semibold for all non-~ characters, if we used ...
|
||||
// 3. Replacing emoji code sequences by ObjectReplacementCharacters with emoji pics.
|
||||
// 4. Interrupting tags in which the text was inserted by any char except a letter.
|
||||
// 5. Applying tags from "_insertedTags" in case we pasted text with tags, not just text.
|
||||
// Rule 4 applies only if we inserted chars not in the middle of a tag (but at the end).
|
||||
void processFormatting(int changedPosition, int changedEnd);
|
||||
|
||||
bool heightAutoupdated();
|
||||
|
||||
int placeholderSkipWidth() const;
|
||||
|
||||
int _minHeight = -1; // < 0 - no autosize
|
||||
int _maxHeight = -1;
|
||||
int _maxLength = -1;
|
||||
SubmitSettings _submitSettings = SubmitSettings::Enter;
|
||||
|
||||
QString _ph, _phelided;
|
||||
int _phAfter = 0;
|
||||
bool _phVisible;
|
||||
anim::ivalue a_phLeft;
|
||||
anim::fvalue a_phAlpha;
|
||||
anim::fvalue a_phColorFocused;
|
||||
Animation _a_appearance;
|
||||
|
||||
TextWithTags _lastTextWithTags;
|
||||
|
||||
// Tags list which we should apply while setText() call or insert from mime data.
|
||||
TagList _insertedTags;
|
||||
bool _insertedTagsAreFromMime;
|
||||
|
||||
// Override insert position and charsAdded from complex text editing
|
||||
// (like drag-n-drop in the same text edit field).
|
||||
int _realInsertPosition = -1;
|
||||
int _realCharsAdded = 0;
|
||||
|
||||
std_::unique_ptr<TagMimeProcessor> _tagMimeProcessor;
|
||||
|
||||
const style::FlatTextarea &_st;
|
||||
|
||||
bool _undoAvailable = false;
|
||||
bool _redoAvailable = false;
|
||||
bool _inDrop = false;
|
||||
bool _inHeightCheck = false;
|
||||
|
||||
int _fakeMargin = 0;
|
||||
|
||||
QTimer _touchTimer;
|
||||
bool _touchPress = false;
|
||||
bool _touchRightButton = false;
|
||||
bool _touchMove = false;
|
||||
QPoint _touchStart;
|
||||
|
||||
bool _correcting = false;
|
||||
|
||||
struct LinkRange {
|
||||
int start;
|
||||
int length;
|
||||
};
|
||||
friend bool operator==(const LinkRange &a, const LinkRange &b);
|
||||
friend bool operator!=(const LinkRange &a, const LinkRange &b);
|
||||
using LinkRanges = QVector<LinkRange>;
|
||||
LinkRanges _links;
|
||||
};
|
||||
|
||||
inline bool operator==(const FlatTextarea::LinkRange &a, const FlatTextarea::LinkRange &b) {
|
||||
return (a.start == b.start) && (a.length == b.length);
|
||||
}
|
||||
inline bool operator!=(const FlatTextarea::LinkRange &a, const FlatTextarea::LinkRange &b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
class FlatInput : public QLineEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
|
||||
public:
|
||||
FlatInput(QWidget *parent, const style::flatInput &st, const QString &ph = QString(), const QString &val = QString());
|
||||
FlatInput(QWidget *parent, const style::FlatInput &st, const QString &ph = QString(), const QString &val = QString());
|
||||
|
||||
void notaBene();
|
||||
|
||||
@ -49,7 +267,7 @@ public:
|
||||
return _oldtext;
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void onTextChange(const QString &text);
|
||||
void onTextEdited();
|
||||
|
||||
@ -105,7 +323,7 @@ private:
|
||||
Animation _a_appearance;
|
||||
|
||||
int _notingBene;
|
||||
const style::flatInput &_st;
|
||||
const style::FlatInput &_st;
|
||||
|
||||
QTimer _touchTimer;
|
||||
bool _touchPress, _touchRightButton, _touchMove;
|
||||
@ -116,9 +334,9 @@ class CountryCodeInput : public FlatInput {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CountryCodeInput(QWidget *parent, const style::flatInput &st);
|
||||
CountryCodeInput(QWidget *parent, const style::FlatInput &st);
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void startErasing(QKeyEvent *e);
|
||||
void codeSelected(const QString &code);
|
||||
|
||||
@ -138,9 +356,9 @@ class PhonePartInput : public FlatInput {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PhonePartInput(QWidget *parent, const style::flatInput &st);
|
||||
PhonePartInput(QWidget *parent, const style::FlatInput &st);
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void addedToNumber(const QString &added);
|
||||
void onChooseCode(const QString &code);
|
||||
|
||||
@ -221,7 +439,7 @@ public:
|
||||
_inner.clearFocus();
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void onTouchTimer();
|
||||
|
||||
void onDocumentContentsChange(int position, int charsRemoved, int charsAdded);
|
||||
@ -392,7 +610,7 @@ public:
|
||||
_inner.setTextCursor(c);
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void onTouchTimer();
|
||||
|
||||
void onDocumentContentsChange(int position, int charsRemoved, int charsAdded);
|
||||
@ -497,7 +715,7 @@ private:
|
||||
|
||||
class MaskedInputField : public QLineEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
T_WIDGET
|
||||
|
||||
public:
|
||||
MaskedInputField(QWidget *parent, const style::InputField &st, const QString &placeholder = QString(), const QString &val = QString());
|
||||
@ -539,7 +757,7 @@ public:
|
||||
updatePlaceholder();
|
||||
}
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void onTextChange(const QString &text);
|
||||
void onCursorPositionChanged(int oldPosition, int position);
|
||||
|
||||
@ -610,9 +828,9 @@ private:
|
||||
QPoint _touchStart;
|
||||
};
|
||||
|
||||
class PasswordField : public MaskedInputField {
|
||||
class PasswordInput : public MaskedInputField {
|
||||
public:
|
||||
PasswordField(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString());
|
||||
PasswordInput(QWidget *parent, const style::InputField &st, const QString &ph = QString(), const QString &val = QString());
|
||||
|
||||
};
|
||||
|
||||
@ -655,3 +873,5 @@ private:
|
||||
QVector<int> _pattern;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "lang.h"
|
||||
|
||||
namespace Ui {
|
||||
|
@ -22,10 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
class InputField;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class InputField;
|
||||
class IconButton;
|
||||
|
||||
class MultiSelect : public TWidget {
|
||||
@ -153,7 +152,7 @@ private:
|
||||
int _fieldLeft = 0;
|
||||
int _fieldTop = 0;
|
||||
int _fieldWidth = 0;
|
||||
ChildWidget<InputField> _field;
|
||||
ChildWidget<Ui::InputField> _field;
|
||||
ChildWidget<Ui::IconButton> _cancel;
|
||||
|
||||
int _newHeight = 0;
|
||||
|
@ -35,6 +35,12 @@ LinkButton {
|
||||
overFont: font;
|
||||
}
|
||||
|
||||
RippleAnimation {
|
||||
color: color;
|
||||
showDuration: int;
|
||||
hideDuration: int;
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
color: color;
|
||||
overColor: color;
|
||||
@ -53,6 +59,188 @@ FlatButton {
|
||||
overFont: font;
|
||||
duration: int;
|
||||
cursor: cursor;
|
||||
|
||||
ripple: RippleAnimation;
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
textFg: color;
|
||||
textFgOver: color;
|
||||
textBg: color; // rect of textBg with rounded rect of textBgOver upon it
|
||||
textBgOver: color;
|
||||
|
||||
secondaryTextFg: color;
|
||||
secondaryTextFgOver: color;
|
||||
secondarySkip: pixels;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
padding: margins;
|
||||
|
||||
textTop: pixels;
|
||||
downTextTop: pixels;
|
||||
|
||||
icon: icon;
|
||||
|
||||
font: font;
|
||||
|
||||
ripple: RippleAnimation;
|
||||
}
|
||||
|
||||
Checkbox {
|
||||
textFg: color;
|
||||
textBg: color;
|
||||
|
||||
checkBg: color;
|
||||
checkFg: color;
|
||||
checkFgOver: color;
|
||||
checkFgActive: color;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
|
||||
textPosition: point;
|
||||
diameter: pixels;
|
||||
thickness: pixels;
|
||||
checkIcon: icon;
|
||||
|
||||
font: font;
|
||||
duration: int;
|
||||
}
|
||||
|
||||
Radiobutton {
|
||||
textFg: color;
|
||||
textBg: color;
|
||||
|
||||
checkBg: color;
|
||||
checkFg: color;
|
||||
checkFgOver: color;
|
||||
checkFgActive: color;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
|
||||
textPosition: point;
|
||||
diameter: pixels;
|
||||
thickness: pixels;
|
||||
checkSkip: pixels;
|
||||
|
||||
font: font;
|
||||
duration: int;
|
||||
}
|
||||
|
||||
FlatTextarea {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
width: pixels;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: pixels;
|
||||
phDuration: int;
|
||||
}
|
||||
|
||||
FlatInput {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
bgActive: color;
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
icon: icon;
|
||||
|
||||
borderWidth: pixels;
|
||||
borderColor: color;
|
||||
borderActive: color;
|
||||
borderError: color;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: pixels;
|
||||
phDuration: int;
|
||||
}
|
||||
|
||||
InputArea {
|
||||
textBg: color;
|
||||
textFg: color;
|
||||
textMargins: margins;
|
||||
|
||||
placeholderFg: color;
|
||||
placeholderFgActive: color;
|
||||
placeholderMargins: margins;
|
||||
placeholderAlign: align;
|
||||
placeholderShift: pixels;
|
||||
|
||||
duration: int;
|
||||
|
||||
borderFg: color;
|
||||
borderFgActive: color;
|
||||
borderFgError: color;
|
||||
|
||||
border: pixels;
|
||||
borderActive: pixels;
|
||||
borderError: pixels;
|
||||
|
||||
font: font;
|
||||
|
||||
width: pixels;
|
||||
heightMin: pixels;
|
||||
heightMax: pixels;
|
||||
}
|
||||
|
||||
InputField {
|
||||
textBg: color;
|
||||
textFg: color;
|
||||
textMargins: margins;
|
||||
textAlign: align;
|
||||
|
||||
placeholderFg: color;
|
||||
placeholderFgActive: color;
|
||||
placeholderMargins: margins;
|
||||
placeholderAlign: align;
|
||||
placeholderShift: pixels;
|
||||
|
||||
duration: int;
|
||||
|
||||
borderFg: color;
|
||||
borderFgActive: color;
|
||||
borderFgError: color;
|
||||
|
||||
border: pixels;
|
||||
borderActive: pixels;
|
||||
borderError: pixels;
|
||||
|
||||
font: font;
|
||||
|
||||
width: pixels;
|
||||
height: pixels;
|
||||
}
|
||||
|
||||
OutlineButton {
|
||||
outlineWidth: pixels;
|
||||
outlineFg: color;
|
||||
outlineFgOver: color;
|
||||
|
||||
textBg: color;
|
||||
textBgOver: color;
|
||||
|
||||
textFg: color;
|
||||
textFgOver: color;
|
||||
|
||||
font: font;
|
||||
padding: margins;
|
||||
}
|
||||
|
||||
IconButton {
|
||||
@ -66,6 +254,10 @@ IconButton {
|
||||
iconPositionDown: point;
|
||||
|
||||
duration: int;
|
||||
|
||||
rippleAreaPosition: point;
|
||||
rippleAreaSize: pixels;
|
||||
ripple: RippleAnimation;
|
||||
}
|
||||
|
||||
Shadow {
|
||||
@ -232,6 +424,194 @@ defaultLinkButton: LinkButton {
|
||||
overFont: linkOverFont;
|
||||
}
|
||||
|
||||
defaultRippleAnimation: RippleAnimation {
|
||||
color: windowOverBg;
|
||||
showDuration: 200;
|
||||
hideDuration: 200;
|
||||
}
|
||||
|
||||
emptyRippleAnimation: RippleAnimation {
|
||||
}
|
||||
|
||||
defaultActiveButton: RoundButton {
|
||||
textFg: activeButtonFg;
|
||||
textFgOver: activeButtonFgOver;
|
||||
secondaryTextFg: activeButtonSecondaryFg;
|
||||
secondaryTextFgOver: activeButtonSecondaryFgOver;
|
||||
textBg: activeButtonBg;
|
||||
textBgOver: activeButtonBgOver;
|
||||
|
||||
secondarySkip: 7px;
|
||||
|
||||
width: -34px;
|
||||
height: 34px;
|
||||
padding: margins(0px, 0px, 0px, 0px);
|
||||
|
||||
textTop: 8px;
|
||||
downTextTop: 8px;
|
||||
|
||||
font: semiboldFont;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: activeButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
||||
defaultLightButton: RoundButton(defaultActiveButton) {
|
||||
textFg: lightButtonFg;
|
||||
textFgOver: lightButtonFgOver;
|
||||
textBg: lightButtonBg;
|
||||
textBgOver: lightButtonBgOver;
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: lightButtonBgRipple;
|
||||
}
|
||||
}
|
||||
|
||||
defaultInputFont: font(17px);
|
||||
defaultFlatInput: FlatInput {
|
||||
textColor: #000000;
|
||||
bgColor: #f2f2f2;
|
||||
bgActive: #ffffff;
|
||||
width: 210px;
|
||||
height: 40px;
|
||||
align: align(left);
|
||||
textMrg: margins(5px, 5px, 5px, 5px);
|
||||
font: defaultInputFont;
|
||||
cursor: cursor(text);
|
||||
|
||||
borderWidth: 2px;
|
||||
borderColor: #f2f2f2;
|
||||
borderActive: #54c3f3;
|
||||
borderError: #ed8080;
|
||||
|
||||
phColor: #808080;
|
||||
phFocusColor: #aaaaaa;
|
||||
phAlign: align(left);
|
||||
phPos: point(2px, 0px);
|
||||
phShift: 50px;
|
||||
phDuration: 100;
|
||||
}
|
||||
|
||||
defaultLeftOutlineButton: OutlineButton {
|
||||
outlineWidth: 3px;
|
||||
outlineFg: windowBg;
|
||||
outlineFgOver: windowActiveBg;
|
||||
|
||||
textBg: windowBg;
|
||||
textBgOver: #f2f7fa;
|
||||
|
||||
textFg: windowActiveTextFg;
|
||||
textFgOver: windowActiveTextFg;
|
||||
|
||||
font: normalFont;
|
||||
padding: margins(11px, 5px, 11px, 5px);
|
||||
}
|
||||
attentionLeftOutlineButton: OutlineButton(defaultLeftOutlineButton) {
|
||||
outlineFgOver: #e43f3f;
|
||||
|
||||
textBgOver: #faf2f2;
|
||||
|
||||
textFg: #d15948;
|
||||
textFgOver: #d15948;
|
||||
}
|
||||
|
||||
defaultInputArea: InputArea {
|
||||
textBg: windowBg;
|
||||
textFg: windowTextFg;
|
||||
textMargins: margins(5px, 6px, 5px, 4px);
|
||||
|
||||
placeholderFg: #999999;
|
||||
placeholderFgActive: #aaaaaa;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
placeholderAlign: align(topleft);
|
||||
placeholderShift: 50px;
|
||||
duration: 120;
|
||||
|
||||
borderFg: #e0e0e0;
|
||||
borderFgActive: #62c0f7;
|
||||
borderFgError: #e48383;
|
||||
|
||||
border: 1px;
|
||||
borderActive: 2px;
|
||||
borderError: 2px;
|
||||
|
||||
font: boxTextFont;
|
||||
|
||||
heightMin: 32px;
|
||||
heightMax: 128px;
|
||||
}
|
||||
|
||||
defaultInputField: InputField {
|
||||
textBg: windowBg;
|
||||
textFg: windowTextFg;
|
||||
textMargins: margins(0px, 6px, 0px, 4px);
|
||||
textAlign: align(topleft);
|
||||
|
||||
placeholderFg: #999999;
|
||||
placeholderFgActive: #aaaaaa;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
placeholderAlign: align(topleft);
|
||||
placeholderShift: 50px;
|
||||
duration: 120;
|
||||
|
||||
borderFg: #e0e0e0;
|
||||
borderFgActive: #62c0f7;
|
||||
borderFgError: #e48383;
|
||||
|
||||
border: 1px;
|
||||
borderActive: 2px;
|
||||
borderError: 2px;
|
||||
|
||||
font: boxTextFont;
|
||||
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
defaultCheckboxIcon: icon {{ "default_checkbox_check", windowActiveFg, point(4px, 7px) }};
|
||||
|
||||
defaultCheckbox: Checkbox {
|
||||
textFg: windowTextFg;
|
||||
textBg: windowBg;
|
||||
|
||||
checkBg: #ffffff;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #b3b3b3;
|
||||
checkFgActive: windowActiveBg;
|
||||
|
||||
width: -44px;
|
||||
height: 22px;
|
||||
|
||||
textPosition: point(32px, 2px);
|
||||
diameter: 22px;
|
||||
thickness: 2px;
|
||||
checkIcon: defaultCheckboxIcon;
|
||||
|
||||
font: normalFont;
|
||||
duration: 120;
|
||||
}
|
||||
|
||||
defaultRadiobutton: Radiobutton {
|
||||
textFg: windowTextFg;
|
||||
textBg: windowBg;
|
||||
|
||||
checkBg: #ffffff;
|
||||
checkFg: #b3b3b3;
|
||||
checkFgOver: #bfbfbf;
|
||||
checkFgActive: #4eb3ee;
|
||||
|
||||
width: -46px;
|
||||
height: 22px;
|
||||
|
||||
textPosition: point(34px, 0px);
|
||||
diameter: 22px;
|
||||
thickness: 2px;
|
||||
checkSkip: 65px; // * 0.1
|
||||
|
||||
font: boxTextFont;
|
||||
duration: 120;
|
||||
}
|
||||
|
||||
defaultIconButton: IconButton {
|
||||
iconPosition: point(-1px, -1px);
|
||||
iconPositionDown: point(-1px, -1px);
|
||||
|
@ -58,6 +58,7 @@ void MainWindow::init() {
|
||||
}
|
||||
|
||||
initSize();
|
||||
updateUnreadCounter();
|
||||
}
|
||||
|
||||
HitTestResult MainWindow::hitTest(const QPoint &p) const {
|
||||
|
@ -26,8 +26,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "mainwindow.h"
|
||||
#include "lang.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace Window {
|
||||
@ -225,7 +227,7 @@ void Manager::moveWidgets() {
|
||||
}
|
||||
|
||||
if (count > 1 || !_queuedNotifications.isEmpty()) {
|
||||
auto deltaY = st::notifyHideAll.height + st::notifyDeltaY;
|
||||
auto deltaY = st::notifyHideAllHeight + st::notifyDeltaY;
|
||||
if (!_hideAll) {
|
||||
_hideAll = new HideAllButton(notificationStartPosition(), lastShiftCurrent, notificationShiftDirection());
|
||||
}
|
||||
@ -735,17 +737,17 @@ void Notification::showReplyField() {
|
||||
}
|
||||
stopHiding();
|
||||
|
||||
_background = new Background(this);
|
||||
_background.create(this);
|
||||
_background->setGeometry(0, st::notifyMinHeight, width(), st::notifySendReply.height + st::notifyBorderWidth);
|
||||
_background->show();
|
||||
|
||||
_replyArea = new InputArea(this, st::notifyReplyArea, lang(lng_message_ph), QString());
|
||||
_replyArea.create(this, st::notifyReplyArea, lang(lng_message_ph), QString());
|
||||
_replyArea->resize(width() - st::notifySendReply.width - 2 * st::notifyBorderWidth, st::notifySendReply.height);
|
||||
_replyArea->moveToLeft(st::notifyBorderWidth, st::notifyMinHeight);
|
||||
_replyArea->show();
|
||||
_replyArea->setFocus();
|
||||
_replyArea->setMaxLength(MaxMessageSize);
|
||||
_replyArea->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||
_replyArea->setCtrlEnterSubmit(Ui::CtrlEnterSubmitBoth);
|
||||
|
||||
// Catch mouse press event to activate the window.
|
||||
Sandbox::installEventFilter(this);
|
||||
@ -860,8 +862,8 @@ Notification::~Notification() {
|
||||
HideAllButton::HideAllButton(QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection) {
|
||||
setCursor(style::cur_pointer);
|
||||
|
||||
auto position = computePosition(st::notifyHideAll.height);
|
||||
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAll.height);
|
||||
auto position = computePosition(st::notifyHideAllHeight);
|
||||
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAllHeight);
|
||||
hide();
|
||||
createWinId();
|
||||
|
||||
@ -913,7 +915,7 @@ void HideAllButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
p.setClipRect(e->rect());
|
||||
|
||||
p.fillRect(rect(), _mouseOver ? st::notifyHideAll.textBgOver : st::notifyHideAll.textBg);
|
||||
p.fillRect(rect(), _mouseOver ? st::lightButtonBgOver : st::lightButtonBg);
|
||||
p.fillRect(0, 0, width(), st::notifyBorderWidth, st::notifyBorder);
|
||||
p.fillRect(0, height() - st::notifyBorderWidth, width(), st::notifyBorderWidth, st::notifyBorder);
|
||||
p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, height() - 2 * st::notifyBorderWidth, st::notifyBorder);
|
||||
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
class RoundButton;
|
||||
class InputArea;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
@ -248,7 +249,7 @@ private:
|
||||
ChildWidget<Ui::IconButton> _close;
|
||||
ChildWidget<Ui::RoundButton> _reply;
|
||||
ChildWidget<Background> _background = { nullptr };
|
||||
ChildWidget<InputArea> _replyArea = { nullptr };
|
||||
ChildWidget<Ui::InputArea> _replyArea = { nullptr };
|
||||
ChildWidget<Ui::IconButton> _replySend = { nullptr };
|
||||
bool _waitingForInput = true;
|
||||
|
||||
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "window/slide_animation.h"
|
||||
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace Window {
|
||||
|
||||
void SlideAnimation::paintContents(Painter &p, const QRect &update) const {
|
||||
|
@ -21,7 +21,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "window/top_bar_widget.h"
|
||||
|
||||
#include "styles/style_history.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "boxes/addcontactbox.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
@ -41,7 +40,7 @@ TopBarWidget::TopBarWidget(MainWidget *w) : TWidget(w)
|
||||
, _clearSelection(this, lang(lng_selected_clear), st::topBarClearButton)
|
||||
, _forward(this, lang(lng_selected_forward), st::defaultActiveButton)
|
||||
, _delete(this, lang(lng_selected_delete), st::defaultActiveButton)
|
||||
, _info(this, nullptr, st::infoButton)
|
||||
, _info(this, nullptr, st::topBarInfoButton)
|
||||
, _mediaType(this, lang(lng_media_type), st::topBarButton)
|
||||
, _search(this, st::topBarSearch)
|
||||
, _menuToggle(this, st::topBarMenuToggle) {
|
||||
@ -93,15 +92,23 @@ void TopBarWidget::onSearch() {
|
||||
void TopBarWidget::showMenu() {
|
||||
if (auto main = App::main()) {
|
||||
if (auto peer = main->peer()) {
|
||||
_menu.create(App::main());
|
||||
App::main()->fillPeerMenu(peer, [this](const QString &text, base::lambda_unique<void()> callback) {
|
||||
return _menu->addAction(text, std_::move(callback));
|
||||
});
|
||||
_menu->setHiddenCallback([this] {
|
||||
_menu.destroyDelayed();
|
||||
});
|
||||
_menu->moveToRight(0, 0);
|
||||
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
||||
if (auto menu = _menu.ptr()) {
|
||||
_menu = nullptr;
|
||||
_menuToggle->removeEventFilter(menu);
|
||||
menu->setHiddenCallback([menu] { menu->deleteLater(); });
|
||||
menu->hideAnimated(Ui::DropdownMenu::HideOption::IgnoreShow);
|
||||
} else {
|
||||
_menu.create(App::main());
|
||||
_menuToggle->installEventFilter(_menu);
|
||||
App::main()->fillPeerMenu(peer, [this](const QString &text, base::lambda_unique<void()> callback) {
|
||||
return _menu->addAction(text, std_::move(callback));
|
||||
});
|
||||
_menu->setHiddenCallback([this] {
|
||||
_menu.destroyDelayed();
|
||||
});
|
||||
_menu->moveToRight(st::topBarMenuPosition.x(), st::topBarMenuPosition.y());
|
||||
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,7 @@ notifyDeltaX: 6px;
|
||||
notifyDeltaY: 7px;
|
||||
notifyActionsDuration: 200;
|
||||
|
||||
notifyHideAll: RoundButton(defaultBoxButton) {
|
||||
}
|
||||
notifyHideAllHeight: 36px;
|
||||
|
||||
notifyReplyArea: InputArea(defaultInputArea) {
|
||||
font: normalFont;
|
||||
@ -156,6 +155,78 @@ titleButtonClose: IconButton(titleButtonMinimize) {
|
||||
};
|
||||
}
|
||||
|
||||
// Legacy top bar.
|
||||
topBarHeight: 54px;
|
||||
topBarMenuPosition: point(-2px, 37px);
|
||||
topBarDuration: 200;
|
||||
topBarBackward: icon {{ "title_back", #a3a3a3 }};
|
||||
topBarForwardAlpha: 0.6;
|
||||
topBarBack: icon {{ "title_back", #259fd8 }};
|
||||
topBarBackAlpha: 0.8;
|
||||
topBarBackColor: #005faf;
|
||||
topBarBackFont: font(16px);
|
||||
topBarArrowPadding: margins(39px, 8px, 17px, 8px);
|
||||
topBarMinPadding: 5px;
|
||||
topBarButton: RoundButton {
|
||||
textFg: btnYesColor;
|
||||
textFgOver: btnYesColor;
|
||||
secondaryTextFg: btnYesColor;
|
||||
secondaryTextFgOver: btnYesColor;
|
||||
textBg: windowBg;
|
||||
textBgOver: #edf4f7;
|
||||
|
||||
width: -22px;
|
||||
height: 28px;
|
||||
padding: margins(0px, 14px, 12px, 12px);
|
||||
|
||||
textTop: 6px;
|
||||
downTextTop: 6px;
|
||||
|
||||
font: font(fsize);
|
||||
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: lightButtonBgRipple;
|
||||
}
|
||||
}
|
||||
topBarClearButton: RoundButton(defaultLightButton) {
|
||||
width: -18px;
|
||||
}
|
||||
topBarSearch: IconButton {
|
||||
width: 44px;
|
||||
height: topBarHeight;
|
||||
|
||||
icon: icon {{ "title_search", menuIconFg }};
|
||||
iconOver: icon {{ "title_search", menuIconFgOver }};
|
||||
|
||||
iconPosition: point(15px, 18px);
|
||||
iconPositionDown: point(15px, 18px);
|
||||
|
||||
rippleAreaPosition: point(8px, 11px);
|
||||
rippleAreaSize: 32px;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
topBarMenuToggle: IconButton(topBarSearch) {
|
||||
icon: icon {{ "title_menu_dots", menuIconFg }};
|
||||
iconOver: icon {{ "title_menu_dots", menuIconFgOver }};
|
||||
|
||||
iconPosition: point(15px, 17px);
|
||||
iconPositionDown: point(15px, 17px);
|
||||
|
||||
rippleAreaPosition: point(3px, 11px);
|
||||
rippleAreaSize: 32px;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
topBarActionSkip: 10px;
|
||||
|
||||
PeerAvatarButton {
|
||||
size: pixels;
|
||||
photoSize: pixels;
|
||||
}
|
||||
topBarInfoButton: PeerAvatarButton {
|
||||
size: topBarHeight;
|
||||
photoSize: 42px;
|
||||
}
|
||||
|
||||
// Mac specific
|
||||
|
||||
macAccessoryWidth: 450.;
|
||||
|
@ -3,4 +3,4 @@ AppVersionStrMajor 0.10
|
||||
AppVersionStrSmall 0.10.20
|
||||
AppVersionStr 0.10.20
|
||||
AlphaChannel 0
|
||||
BetaVersion 10019006
|
||||
BetaVersion 10019007
|
||||
|
@ -462,6 +462,8 @@
|
||||
'<(src_loc)/ui/effects/radial_animation.h',
|
||||
'<(src_loc)/ui/effects/rect_shadow.cpp',
|
||||
'<(src_loc)/ui/effects/rect_shadow.h',
|
||||
'<(src_loc)/ui/effects/ripple_animation.cpp',
|
||||
'<(src_loc)/ui/effects/ripple_animation.h',
|
||||
'<(src_loc)/ui/effects/round_image_checkbox.cpp',
|
||||
'<(src_loc)/ui/effects/round_image_checkbox.h',
|
||||
'<(src_loc)/ui/effects/widget_fade_wrap.cpp',
|
||||
@ -504,6 +506,8 @@
|
||||
'<(src_loc)/ui/widgets/filled_slider.h',
|
||||
'<(src_loc)/ui/widgets/inner_dropdown.cpp',
|
||||
'<(src_loc)/ui/widgets/inner_dropdown.h',
|
||||
'<(src_loc)/ui/widgets/input_fields.cpp',
|
||||
'<(src_loc)/ui/widgets/input_fields.h',
|
||||
'<(src_loc)/ui/widgets/label_simple.cpp',
|
||||
'<(src_loc)/ui/widgets/label_simple.h',
|
||||
'<(src_loc)/ui/widgets/media_slider.cpp',
|
||||
@ -528,12 +532,8 @@
|
||||
'<(src_loc)/ui/emoji_config.h',
|
||||
'<(src_loc)/ui/filedialog.cpp',
|
||||
'<(src_loc)/ui/filedialog.h',
|
||||
'<(src_loc)/ui/flatinput.cpp',
|
||||
'<(src_loc)/ui/flatinput.h',
|
||||
'<(src_loc)/ui/flatlabel.cpp',
|
||||
'<(src_loc)/ui/flatlabel.h',
|
||||
'<(src_loc)/ui/flattextarea.cpp',
|
||||
'<(src_loc)/ui/flattextarea.h',
|
||||
'<(src_loc)/ui/images.cpp',
|
||||
'<(src_loc)/ui/images.h',
|
||||
'<(src_loc)/ui/scrollarea.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user