| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "ui/chat/chat_style.h"
- #include "ui/chat/chat_theme.h"
- #include "ui/image/image_prepare.h" // ImageRoundRadius
- #include "ui/text/text_custom_emoji.h"
- #include "ui/color_contrast.h"
- #include "ui/painter.h"
- #include "ui/ui_utility.h"
- #include "styles/style_chat.h"
- #include "styles/style_dialogs.h"
- #include "styles/style_widgets.h"
- namespace Ui {
- namespace {
- void EnsureCorners(
- CornersPixmaps &corners,
- int radius,
- const style::color &color,
- const style::color *shadow = nullptr) {
- if (corners.p[0].isNull()) {
- corners = PrepareCornerPixmaps(radius, color, shadow);
- }
- }
- void EnsureBlockquoteCache(
- std::unique_ptr<Text::QuotePaintCache> &cache,
- Fn<ColorIndexValues()> values) {
- if (cache) {
- return;
- }
- cache = std::make_unique<Text::QuotePaintCache>();
- const auto &colors = values();
- cache->bg = colors.bg;
- cache->outlines = colors.outlines;
- cache->icon = colors.name;
- }
- void EnsurePreCache(
- std::unique_ptr<Text::QuotePaintCache> &cache,
- const style::color &color,
- Fn<std::optional<QColor>()> bgOverride) {
- if (cache) {
- return;
- }
- cache = std::make_unique<Text::QuotePaintCache>();
- const auto bg = bgOverride();
- cache->bg = bg.value_or(color->c);
- if (!bg) {
- cache->bg.setAlpha(kDefaultBgOpacity * 255);
- }
- cache->outlines[0] = color->c;
- cache->outlines[0].setAlpha(kDefaultOutline1Opacity * 255);
- cache->outlines[1] = cache->outlines[2] = QColor(0, 0, 0, 0);
- cache->header = color->c;
- cache->header.setAlpha(kDefaultOutline2Opacity * 255);
- cache->icon = cache->outlines[0];
- cache->icon.setAlpha(kDefaultOutline3Opacity * 255);
- }
- } // namespace
- not_null<const MessageStyle*> ChatPaintContext::messageStyle() const {
- return &st->messageStyle(outbg, selected());
- }
- not_null<const MessageImageStyle*> ChatPaintContext::imageStyle() const {
- return &st->imageStyle(selected());
- }
- not_null<Text::QuotePaintCache*> ChatPaintContext::quoteCache(
- uint8 colorIndex) const {
- return !outbg
- ? st->coloredQuoteCache(selected(), colorIndex).get()
- : messageStyle()->quoteCache[
- st->colorPatternIndex(colorIndex)].get();
- }
- int HistoryServiceMsgRadius() {
- static const auto result = [] {
- const auto minMessageHeight = st::msgServicePadding.top()
- + st::msgServiceFont->height
- + st::msgServicePadding.bottom();
- return minMessageHeight / 2;
- }();
- return result;
- }
- int HistoryServiceMsgInvertedRadius() {
- static const auto result = [] {
- const auto minRowHeight = st::msgServiceFont->height;
- return minRowHeight - HistoryServiceMsgRadius();
- }();
- return result;
- }
- int HistoryServiceMsgInvertedShrink() {
- static const auto result = [] {
- return (HistoryServiceMsgInvertedRadius() * 2) / 3;
- }();
- return result;
- }
- ColorIndexValues SimpleColorIndexValues(QColor color, int patternIndex) {
- auto bg = color;
- bg.setAlpha(kDefaultBgOpacity * 255);
- auto result = ColorIndexValues{
- .name = color,
- .bg = bg,
- };
- result.outlines[0] = color;
- result.outlines[0].setAlpha(kDefaultOutline1Opacity * 255);
- if (patternIndex > 1) {
- result.outlines[1] = result.outlines[0];
- result.outlines[1].setAlpha(kDefaultOutline2Opacity * 255);
- result.outlines[2] = result.outlines[0];
- result.outlines[2].setAlpha(kDefaultOutline3Opacity * 255);
- } else if (patternIndex > 0) {
- result.outlines[1] = result.outlines[0];
- result.outlines[1].setAlpha(kDefaultOutlineOpacitySecond * 255);
- result.outlines[2] = QColor(0, 0, 0, 0);
- } else {
- result.outlines[1] = result.outlines[2] = QColor(0, 0, 0, 0);
- }
- return result;
- }
- int BackgroundEmojiData::CacheIndex(
- bool selected,
- bool outbg,
- bool inbubble,
- uint8 colorIndexPlusOne) {
- const auto base = colorIndexPlusOne
- ? (colorIndexPlusOne - 1)
- : (kColorIndexCount + (!inbubble ? 0 : outbg ? 1 : 2));
- return (base * 2) + (selected ? 1 : 0);
- };
- int ColorPatternIndex(
- const ColorIndicesCompressed &indices,
- uint8 colorIndex,
- bool dark) {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- if (!indices.colors
- || colorIndex < kSimpleColorIndexCount) {
- return 0;
- }
- auto &data = (*indices.colors)[colorIndex];
- auto &colors = dark ? data.dark : data.light;
- return colors[2] ? 2 : colors[1] ? 1 : 0;
- }
- ChatStyle::ChatStyle(rpl::producer<ColorIndicesCompressed> colorIndices) {
- if (colorIndices) {
- _colorIndicesLifetime = std::move(
- colorIndices
- ) | rpl::start_with_next([=](ColorIndicesCompressed &&indices) {
- _colorIndices = std::move(indices);
- });
- }
- finalize();
- make(_historyPsaForwardPalette, st::historyPsaForwardPalette);
- make(_imgReplyTextPalette, st::imgReplyTextPalette);
- make(_serviceTextPalette, st::serviceTextPalette);
- make(_priceTagTextPalette, st::priceTagTextPalette);
- make(_historyRepliesInvertedIcon, st::historyRepliesInvertedIcon);
- make(_historyViewsInvertedIcon, st::historyViewsInvertedIcon);
- make(_historyViewsSendingIcon, st::historyViewsSendingIcon);
- make(
- _historyViewsSendingInvertedIcon,
- st::historyViewsSendingInvertedIcon);
- make(_historyPinInvertedIcon, st::historyPinInvertedIcon);
- make(_historySendingIcon, st::historySendingIcon);
- make(_historySendingInvertedIcon, st::historySendingInvertedIcon);
- make(_historySentInvertedIcon, st::historySentInvertedIcon);
- make(_historyReceivedInvertedIcon, st::historyReceivedInvertedIcon);
- make(_msgBotKbUrlIcon, st::msgBotKbUrlIcon);
- make(_msgBotKbPaymentIcon, st::msgBotKbPaymentIcon);
- make(_msgBotKbSwitchPmIcon, st::msgBotKbSwitchPmIcon);
- make(_msgBotKbWebviewIcon, st::msgBotKbWebviewIcon);
- make(_msgBotKbCopyIcon, st::msgBotKbCopyIcon);
- make(_historyFastCommentsIcon, st::historyFastCommentsIcon);
- make(_historyFastShareIcon, st::historyFastShareIcon);
- make(_historyFastTranscribeIcon, st::historyFastTranscribeIcon);
- make(_historyFastTranscribeLock, st::historyFastTranscribeLock);
- make(_historyGoToOriginalIcon, st::historyGoToOriginalIcon);
- make(_historyFastCloseIcon, st::historyFastCloseIcon);
- make(_historyFastMoreIcon, st::historyFastMoreIcon);
- make(_historyMapPoint, st::historyMapPoint);
- make(_historyMapPointInner, st::historyMapPointInner);
- make(_youtubeIcon, st::youtubeIcon);
- make(_videoIcon, st::videoIcon);
- make(_historyPollChoiceRight, st::historyPollChoiceRight);
- make(_historyPollChoiceWrong, st::historyPollChoiceWrong);
- make(
- &MessageStyle::msgBg,
- st::msgInBg,
- st::msgInBgSelected,
- st::msgOutBg,
- st::msgOutBgSelected);
- make(
- &MessageStyle::msgShadow,
- st::msgInShadow,
- st::msgInShadowSelected,
- st::msgOutShadow,
- st::msgOutShadowSelected);
- make(
- &MessageStyle::msgServiceFg,
- st::msgInServiceFg,
- st::msgInServiceFgSelected,
- st::msgOutServiceFg,
- st::msgOutServiceFgSelected);
- make(
- &MessageStyle::msgDateFg,
- st::msgInDateFg,
- st::msgInDateFgSelected,
- st::msgOutDateFg,
- st::msgOutDateFgSelected);
- make(
- &MessageStyle::msgFileThumbLinkFg,
- st::msgFileThumbLinkInFg,
- st::msgFileThumbLinkInFgSelected,
- st::msgFileThumbLinkOutFg,
- st::msgFileThumbLinkOutFgSelected);
- make(
- &MessageStyle::msgFileBg,
- st::msgFileInBg,
- st::msgFileInBgSelected,
- st::msgFileOutBg,
- st::msgFileOutBgSelected);
- make(
- &MessageStyle::msgReplyBarColor,
- st::msgInReplyBarColor,
- st::msgInReplyBarSelColor,
- st::msgOutReplyBarColor,
- st::msgOutReplyBarSelColor);
- make(
- &MessageStyle::msgWaveformActive,
- st::msgWaveformInActive,
- st::msgWaveformInActiveSelected,
- st::msgWaveformOutActive,
- st::msgWaveformOutActiveSelected);
- make(
- &MessageStyle::msgWaveformInactive,
- st::msgWaveformInInactive,
- st::msgWaveformInInactiveSelected,
- st::msgWaveformOutInactive,
- st::msgWaveformOutInactiveSelected);
- make(
- &MessageStyle::historyTextFg,
- st::historyTextInFg,
- st::historyTextInFgSelected,
- st::historyTextOutFg,
- st::historyTextOutFgSelected);
- make(
- &MessageStyle::historyFileNameFg,
- st::historyFileNameInFg,
- st::historyFileNameInFgSelected,
- st::historyFileNameOutFg,
- st::historyFileNameOutFgSelected);
- make(
- &MessageStyle::historyFileRadialFg,
- st::historyFileInRadialFg,
- st::historyFileInRadialFgSelected,
- st::historyFileOutRadialFg,
- st::historyFileOutRadialFgSelected);
- make(
- &MessageStyle::mediaFg,
- st::mediaInFg,
- st::mediaInFgSelected,
- st::mediaOutFg,
- st::mediaOutFgSelected);
- make(
- &MessageStyle::textPalette,
- st::inTextPalette,
- st::inTextPaletteSelected,
- st::outTextPalette,
- st::outTextPaletteSelected);
- make(
- &MessageStyle::semiboldPalette,
- st::inSemiboldPalette,
- st::inTextPaletteSelected,
- st::outSemiboldPalette,
- st::outTextPaletteSelected);
- make(
- &MessageStyle::fwdTextPalette,
- st::inFwdTextPalette,
- st::inFwdTextPaletteSelected,
- st::outFwdTextPalette,
- st::outFwdTextPaletteSelected);
- make(
- &MessageStyle::replyTextPalette,
- st::inReplyTextPalette,
- st::inReplyTextPaletteSelected,
- st::outReplyTextPalette,
- st::outReplyTextPaletteSelected);
- make(
- &MessageStyle::tailLeft,
- st::historyBubbleTailInLeft,
- st::historyBubbleTailInLeftSelected,
- st::historyBubbleTailOutLeft,
- st::historyBubbleTailOutLeftSelected);
- make(
- &MessageStyle::tailRight,
- st::historyBubbleTailInRight,
- st::historyBubbleTailInRightSelected,
- st::historyBubbleTailOutRight,
- st::historyBubbleTailOutRightSelected);
- make(
- &MessageStyle::historyRepliesIcon,
- st::historyRepliesInIcon,
- st::historyRepliesInSelectedIcon,
- st::historyRepliesOutIcon,
- st::historyRepliesOutSelectedIcon);
- make(
- &MessageStyle::historyViewsIcon,
- st::historyViewsInIcon,
- st::historyViewsInSelectedIcon,
- st::historyViewsOutIcon,
- st::historyViewsOutSelectedIcon);
- make(
- &MessageStyle::historyPinIcon,
- st::historyPinInIcon,
- st::historyPinInSelectedIcon,
- st::historyPinOutIcon,
- st::historyPinOutSelectedIcon);
- make(
- &MessageStyle::historySentIcon,
- st::historySentIcon,
- st::historySentSelectedIcon,
- st::historySentIcon,
- st::historySentSelectedIcon);
- make(
- &MessageStyle::historyReceivedIcon,
- st::historyReceivedIcon,
- st::historyReceivedSelectedIcon,
- st::historyReceivedIcon,
- st::historyReceivedSelectedIcon);
- make(
- &MessageStyle::historyPsaIcon,
- st::historyPsaIconIn,
- st::historyPsaIconInSelected,
- st::historyPsaIconOut,
- st::historyPsaIconOutSelected);
- make(
- &MessageStyle::historyCommentsOpen,
- st::historyCommentsOpenIn,
- st::historyCommentsOpenInSelected,
- st::historyCommentsOpenOut,
- st::historyCommentsOpenOutSelected);
- make(
- &MessageStyle::historyComments,
- st::historyCommentsIn,
- st::historyCommentsInSelected,
- st::historyCommentsOut,
- st::historyCommentsOutSelected);
- make(
- &MessageStyle::historyCallArrow,
- st::historyCallArrowIn,
- st::historyCallArrowInSelected,
- st::historyCallArrowOut,
- st::historyCallArrowOutSelected);
- make(
- &MessageStyle::historyCallArrowMissed,
- st::historyCallArrowMissedIn,
- st::historyCallArrowMissedInSelected,
- st::historyCallArrowMissedIn,
- st::historyCallArrowMissedInSelected);
- make(
- &MessageStyle::historyCallIcon,
- st::historyCallInIcon,
- st::historyCallInIconSelected,
- st::historyCallOutIcon,
- st::historyCallOutIconSelected);
- make(
- &MessageStyle::historyCallCameraIcon,
- st::historyCallCameraInIcon,
- st::historyCallCameraInIconSelected,
- st::historyCallCameraOutIcon,
- st::historyCallCameraOutIconSelected);
- make(
- &MessageStyle::historyFilePlay,
- st::historyFileInPlay,
- st::historyFileInPlaySelected,
- st::historyFileOutPlay,
- st::historyFileOutPlaySelected);
- make(
- &MessageStyle::historyFileWaiting,
- st::historyFileInWaiting,
- st::historyFileInWaitingSelected,
- st::historyFileOutWaiting,
- st::historyFileOutWaitingSelected);
- make(
- &MessageStyle::historyFileDownload,
- st::historyFileInDownload,
- st::historyFileInDownloadSelected,
- st::historyFileOutDownload,
- st::historyFileOutDownloadSelected);
- make(
- &MessageStyle::historyFileCancel,
- st::historyFileInCancel,
- st::historyFileInCancelSelected,
- st::historyFileOutCancel,
- st::historyFileOutCancelSelected);
- make(
- &MessageStyle::historyFilePause,
- st::historyFileInPause,
- st::historyFileInPauseSelected,
- st::historyFileOutPause,
- st::historyFileOutPauseSelected);
- make(
- &MessageStyle::historyFileImage,
- st::historyFileInImage,
- st::historyFileInImageSelected,
- st::historyFileOutImage,
- st::historyFileOutImageSelected);
- make(
- &MessageStyle::historyFileDocument,
- st::historyFileInDocument,
- st::historyFileInDocumentSelected,
- st::historyFileOutDocument,
- st::historyFileOutDocumentSelected);
- make(
- &MessageStyle::historyAudioDownload,
- st::historyAudioInDownload,
- st::historyAudioInDownloadSelected,
- st::historyAudioOutDownload,
- st::historyAudioOutDownloadSelected);
- make(
- &MessageStyle::historyAudioCancel,
- st::historyAudioInCancel,
- st::historyAudioInCancelSelected,
- st::historyAudioOutCancel,
- st::historyAudioOutCancelSelected);
- make(
- &MessageStyle::historyQuizTimer,
- st::historyQuizTimerIn,
- st::historyQuizTimerInSelected,
- st::historyQuizTimerOut,
- st::historyQuizTimerOutSelected);
- make(
- &MessageStyle::historyQuizExplain,
- st::historyQuizExplainIn,
- st::historyQuizExplainInSelected,
- st::historyQuizExplainOut,
- st::historyQuizExplainOutSelected);
- make(
- &MessageStyle::historyPollChosen,
- st::historyPollInChosen,
- st::historyPollInChosenSelected,
- st::historyPollOutChosen,
- st::historyPollOutChosenSelected);
- make(
- &MessageStyle::historyPollChoiceRight,
- st::historyPollInChoiceRight,
- st::historyPollInChoiceRightSelected,
- st::historyPollOutChoiceRight,
- st::historyPollOutChoiceRightSelected);
- make(
- &MessageStyle::historyTranscribeIcon,
- st::historyTranscribeInIcon,
- st::historyTranscribeInIconSelected,
- st::historyTranscribeOutIcon,
- st::historyTranscribeOutIconSelected);
- make(
- &MessageStyle::historyTranscribeLock,
- st::historyTranscribeInLock,
- st::historyTranscribeInLockSelected,
- st::historyTranscribeOutLock,
- st::historyTranscribeOutLockSelected);
- make(
- &MessageStyle::historyTranscribeHide,
- st::historyTranscribeInHide,
- st::historyTranscribeInHideSelected,
- st::historyTranscribeOutHide,
- st::historyTranscribeOutHideSelected);
- make(
- &MessageImageStyle::msgDateImgBg,
- st::msgDateImgBg,
- st::msgDateImgBgSelected);
- make(
- &MessageImageStyle::msgServiceBg,
- st::msgServiceBg,
- st::msgServiceBgSelected);
- make(
- &MessageImageStyle::msgShadow,
- st::msgInShadow,
- st::msgInShadowSelected);
- make(
- &MessageImageStyle::historyFileThumbRadialFg,
- st::historyFileThumbRadialFg,
- st::historyFileThumbRadialFgSelected);
- make(
- &MessageImageStyle::historyFileThumbPlay,
- st::historyFileThumbPlay,
- st::historyFileThumbPlaySelected);
- make(
- &MessageImageStyle::historyFileThumbWaiting,
- st::historyFileThumbWaiting,
- st::historyFileThumbWaitingSelected);
- make(
- &MessageImageStyle::historyFileThumbDownload,
- st::historyFileThumbDownload,
- st::historyFileThumbDownloadSelected);
- make(
- &MessageImageStyle::historyFileThumbCancel,
- st::historyFileThumbCancel,
- st::historyFileThumbCancelSelected);
- make(
- &MessageImageStyle::historyFileThumbPause,
- st::historyFileThumbPause,
- st::historyFileThumbPauseSelected);
- make(
- &MessageImageStyle::historyVideoDownload,
- st::historyVideoDownload,
- st::historyVideoDownloadSelected);
- make(
- &MessageImageStyle::historyVideoCancel,
- st::historyVideoCancel,
- st::historyVideoCancelSelected);
- make(
- &MessageImageStyle::historyVideoMessageMute,
- st::historyVideoMessageMute,
- st::historyVideoMessageMuteSelected);
- make(
- &MessageImageStyle::historyVideoMessageTtlIcon,
- st::historyVideoMessageTtlIcon,
- st::historyVideoMessageTtlIconSelected);
- make(
- &MessageImageStyle::historyPageEnlarge,
- st::historyPageEnlarge,
- st::historyPageEnlargeSelected);
- make(
- &MessageStyle::historyVoiceMessageTTL,
- st::historyVoiceMessageInTTL,
- st::historyVoiceMessageInTTLSelected,
- st::historyVoiceMessageOutTTL,
- st::historyVoiceMessageOutTTLSelected);
- make(
- &MessageStyle::liveLocationLongIcon,
- st::liveLocationLongInIcon,
- st::liveLocationLongInIconSelected,
- st::liveLocationLongOutIcon,
- st::liveLocationLongOutIconSelected);
- updateDarkValue();
- }
- ChatStyle::ChatStyle(not_null<const style::palette*> isolated)
- : ChatStyle(rpl::producer<ColorIndicesCompressed>()) {
- assignPalette(isolated);
- }
- ChatStyle::~ChatStyle() = default;
- void ChatStyle::apply(not_null<ChatTheme*> theme) {
- applyCustomPalette(theme->palette());
- }
- void ChatStyle::updateDarkValue() {
- const auto withBg = [&](const QColor &color) {
- return CountContrast(windowBg()->c, color);
- };
- _dark = (withBg({ 0, 0, 0 }) < withBg({ 255, 255, 255 }));
- }
- void ChatStyle::applyCustomPalette(const style::palette *palette) {
- assignPalette(palette ? palette : style::main_palette::get().get());
- if (palette) {
- _defaultPaletteChangeLifetime.destroy();
- } else {
- style::PaletteChanged(
- ) | rpl::start_with_next([=] {
- assignPalette(style::main_palette::get());
- }, _defaultPaletteChangeLifetime);
- }
- }
- void ChatStyle::applyAdjustedServiceBg(QColor serviceBg) {
- auto r = 0, g = 0, b = 0, a = 0;
- serviceBg.getRgb(&r, &g, &b, &a);
- msgServiceBg().set(uchar(r), uchar(g), uchar(b), uchar(a));
- }
- std::span<Text::SpecialColor> ChatStyle::highlightColors() const {
- if (_highlightColors.empty()) {
- const auto push = [&](const style::color &color) {
- _highlightColors.push_back({ &color->p, &color->p });
- };
- // comment, block-comment, prolog, doctype, cdata
- push(statisticsChartLineLightblue());
- // punctuation
- push(statisticsChartLineRed());
- // property, tag, boolean, number,
- // constant, symbol, deleted
- push(statisticsChartLineRed());
- // selector, attr-name, string, char, builtin
- push(statisticsChartLineOrange());
- // operator, entity, url
- push(statisticsChartLineRed());
- // atrule, attr-value, keyword, function
- push(statisticsChartLineBlue());
- // class-name
- push(statisticsChartLinePurple());
- // inserted
- push(statisticsChartLineGreen());
- //push(statisticsChartLineLightgreen());
- //push(statisticsChartLineGolden());
- }
- return _highlightColors;
- }
- void ChatStyle::clearColorIndexCaches() {
- for (auto &style : _messageStyles) {
- for (auto &cache : style.quoteCache) {
- cache = nullptr;
- }
- for (auto &cache : style.replyCache) {
- cache = nullptr;
- }
- }
- for (auto &values : _coloredValues) {
- values.reset();
- }
- for (auto &palette : _coloredTextPalettes) {
- palette.linkFg.reset();
- }
- for (auto &cache : _coloredReplyCaches) {
- cache = nullptr;
- }
- for (auto &cache : _coloredQuoteCaches) {
- cache = nullptr;
- }
- }
- void ChatStyle::assignPalette(not_null<const style::palette*> palette) {
- *static_cast<style::palette*>(this) = *palette;
- style::internal::ResetIcons();
- clearColorIndexCaches();
- for (auto &style : _messageStyles) {
- style.msgBgCornersSmall = {};
- style.msgBgCornersLarge = {};
- style.preCache = nullptr;
- style.textPalette.linkAlwaysActive
- = style.semiboldPalette.linkAlwaysActive
- = (style.textPalette.linkFg->c == style.historyTextFg->c);
- }
- for (auto &style : _imageStyles) {
- style.msgDateImgBgCorners = {};
- style.msgServiceBgCornersSmall = {};
- style.msgServiceBgCornersLarge = {};
- style.msgShadowCornersSmall = {};
- style.msgShadowCornersLarge = {};
- }
- _serviceBgCornersNormal = {};
- _serviceBgCornersInverted = {};
- _msgBotKbOverBgAddCornersSmall = {};
- _msgBotKbOverBgAddCornersLarge = {};
- for (auto &corners : _msgSelectOverlayCorners) {
- corners = {};
- }
- updateDarkValue();
- _paletteChanged.fire({});
- }
- const CornersPixmaps &ChatStyle::serviceBgCornersNormal() const {
- EnsureCorners(
- _serviceBgCornersNormal,
- HistoryServiceMsgRadius(),
- msgServiceBg());
- return _serviceBgCornersNormal;
- }
- const CornersPixmaps &ChatStyle::serviceBgCornersInverted() const {
- if (_serviceBgCornersInverted.p[0].isNull()) {
- _serviceBgCornersInverted = PrepareInvertedCornerPixmaps(
- HistoryServiceMsgInvertedRadius(),
- msgServiceBg());
- }
- return _serviceBgCornersInverted;
- }
- const MessageStyle &ChatStyle::messageStyle(bool outbg, bool selected) const {
- auto &result = messageStyleRaw(outbg, selected);
- EnsureCorners(
- result.msgBgCornersSmall,
- BubbleRadiusSmall(),
- result.msgBg,
- &result.msgShadow);
- EnsureCorners(
- result.msgBgCornersLarge,
- BubbleRadiusLarge(),
- result.msgBg,
- &result.msgShadow);
- const auto &replyBar = result.msgReplyBarColor->c;
- for (auto i = 0; i != kColorPatternsCount; ++i) {
- EnsureBlockquoteCache(
- result.replyCache[i],
- [&] { return SimpleColorIndexValues(replyBar, i); });
- if (!result.quoteCache[i]) {
- result.quoteCache[i] = std::make_unique<Text::QuotePaintCache>(
- *result.replyCache[i]);
- }
- }
- const auto preBgOverride = [&] {
- return _dark ? QColor(0, 0, 0, 192) : std::optional<QColor>();
- };
- EnsurePreCache(
- result.preCache,
- (selected
- ? result.textPalette.selectMonoFg
- : result.textPalette.monoFg),
- preBgOverride);
- return result;
- }
- const MessageImageStyle &ChatStyle::imageStyle(bool selected) const {
- auto &result = imageStyleRaw(selected);
- EnsureCorners(
- result.msgDateImgBgCorners,
- (st::msgDateImgPadding.y() * 2 + st::normalFont->height) / 2,
- result.msgDateImgBg);
- EnsureCorners(
- result.msgServiceBgCornersSmall,
- BubbleRadiusSmall(),
- result.msgServiceBg);
- EnsureCorners(
- result.msgServiceBgCornersLarge,
- BubbleRadiusLarge(),
- result.msgServiceBg);
- EnsureCorners(
- result.msgShadowCornersSmall,
- BubbleRadiusSmall(),
- result.msgShadow);
- EnsureCorners(
- result.msgShadowCornersLarge,
- BubbleRadiusLarge(),
- result.msgShadow);
- return result;
- }
- int ChatStyle::colorPatternIndex(uint8 colorIndex) const {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- if (!_colorIndices.colors
- || colorIndex < kSimpleColorIndexCount) {
- return 0;
- }
- auto &data = (*_colorIndices.colors)[colorIndex];
- auto &colors = _dark ? data.dark : data.light;
- return colors[2] ? 2 : colors[1] ? 1 : 0;
- }
- ColorIndexValues ChatStyle::computeColorIndexValues(
- bool selected,
- uint8 colorIndex) const {
- if (!_colorIndices.colors) {
- colorIndex %= kSimpleColorIndexCount;
- }
- if (colorIndex < kSimpleColorIndexCount) {
- const auto list = std::array{
- &historyPeer1NameFg(),
- &historyPeer2NameFg(),
- &historyPeer3NameFg(),
- &historyPeer4NameFg(),
- &historyPeer5NameFg(),
- &historyPeer6NameFg(),
- &historyPeer7NameFg(),
- &historyPeer8NameFg(),
- };
- const auto listSelected = std::array{
- &historyPeer1NameFgSelected(),
- &historyPeer2NameFgSelected(),
- &historyPeer3NameFgSelected(),
- &historyPeer4NameFgSelected(),
- &historyPeer5NameFgSelected(),
- &historyPeer6NameFgSelected(),
- &historyPeer7NameFgSelected(),
- &historyPeer8NameFgSelected(),
- };
- const auto paletteIndex = ColorIndexToPaletteIndex(colorIndex);
- auto result = ColorIndexValues{
- .name = (*(selected ? listSelected : list)[paletteIndex])->c,
- };
- result.bg = result.name;
- result.bg.setAlpha(kDefaultBgOpacity * 255);
- result.outlines[0] = result.name;
- result.outlines[0].setAlpha(kDefaultOutline1Opacity * 255);
- result.outlines[1] = result.outlines[2] = QColor(0, 0, 0, 0);
- return result;
- }
- auto &data = (*_colorIndices.colors)[colorIndex];
- auto &colors = _dark ? data.dark : data.light;
- if (!colors[0]) {
- return computeColorIndexValues(
- selected,
- colorIndex % kSimpleColorIndexCount);
- }
- const auto color = [&](int index) {
- const auto v = colors[index];
- return v
- ? QColor((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
- : QColor(0, 0, 0, 0);
- };
- auto result = ColorIndexValues{
- .outlines = { color(0), color(1), color(2) }
- };
- result.bg = result.outlines[0];
- result.bg.setAlpha(kDefaultBgOpacity * 255);
- result.name = result.outlines[0];
- return result;
- }
- not_null<Text::QuotePaintCache*> ChatStyle::serviceQuoteCache(
- bool twoColored) const {
- const auto index = (twoColored ? 1 : 0);
- const auto &service = msgServiceFg()->c;
- EnsureBlockquoteCache(
- _serviceQuoteCache[index],
- [&] { return SimpleColorIndexValues(service, twoColored); });
- return _serviceQuoteCache[index].get();
- }
- not_null<Text::QuotePaintCache*> ChatStyle::serviceReplyCache(
- bool twoColored) const {
- const auto index = (twoColored ? 1 : 0);
- const auto &service = msgServiceFg()->c;
- EnsureBlockquoteCache(
- _serviceReplyCache[index],
- [&] { return SimpleColorIndexValues(service, twoColored); });
- return _serviceReplyCache[index].get();
- }
- const ColorIndexValues &ChatStyle::coloredValues(
- bool selected,
- uint8 colorIndex) const {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- const auto shift = (selected ? kColorIndexCount : 0);
- auto &result = _coloredValues[shift + colorIndex];
- if (!result) {
- result.emplace(computeColorIndexValues(selected, colorIndex));
- }
- return *result;
- }
- const style::TextPalette &ChatStyle::coloredTextPalette(
- bool selected,
- uint8 colorIndex) const {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- const auto shift = (selected ? kColorIndexCount : 0);
- auto &result = _coloredTextPalettes[shift + colorIndex];
- if (!result.linkFg) {
- result.linkFg.emplace(coloredValues(selected, colorIndex).name);
- make(
- result.data,
- (selected
- ? st::inReplyTextPaletteSelected
- : st::inReplyTextPalette));
- result.data.linkFg = result.linkFg->color();
- result.data.selectLinkFg = result.data.linkFg;
- }
- return result.data;
- }
- not_null<BackgroundEmojiData*> ChatStyle::backgroundEmojiData(
- uint64 id) const {
- return &_backgroundEmojis[id];
- }
- not_null<Text::QuotePaintCache*> ChatStyle::coloredQuoteCache(
- bool selected,
- uint8 colorIndex) const {
- return coloredCache(_coloredQuoteCaches, selected, colorIndex);
- }
- not_null<Text::QuotePaintCache*> ChatStyle::coloredReplyCache(
- bool selected,
- uint8 colorIndex) const {
- return coloredCache(_coloredReplyCaches, selected, colorIndex);
- }
- not_null<Text::QuotePaintCache*> ChatStyle::coloredCache(
- ColoredQuotePaintCaches &caches,
- bool selected,
- uint8 colorIndex) const {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- const auto shift = (selected ? kColorIndexCount : 0);
- auto &cache = caches[shift + colorIndex];
- EnsureBlockquoteCache(cache, [&] {
- return coloredValues(selected, colorIndex);
- });
- return cache.get();
- }
- const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersSmall() const {
- EnsureCorners(
- _msgBotKbOverBgAddCornersSmall,
- BubbleRadiusSmall(),
- msgBotKbOverBgAdd());
- return _msgBotKbOverBgAddCornersSmall;
- }
- const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersLarge() const {
- EnsureCorners(
- _msgBotKbOverBgAddCornersLarge,
- BubbleRadiusLarge(),
- msgBotKbOverBgAdd());
- return _msgBotKbOverBgAddCornersLarge;
- }
- const CornersPixmaps &ChatStyle::msgSelectOverlayCorners(
- CachedCornerRadius radius) const {
- const auto index = static_cast<int>(radius);
- Assert(index >= 0 && index < int(CachedCornerRadius::kCount));
- EnsureCorners(
- _msgSelectOverlayCorners[index],
- CachedCornerRadiusValue(radius),
- msgSelectOverlay());
- return _msgSelectOverlayCorners[index];
- }
- MessageStyle &ChatStyle::messageStyleRaw(bool outbg, bool selected) const {
- return _messageStyles[(outbg ? 2 : 0) + (selected ? 1 : 0)];
- }
- MessageStyle &ChatStyle::messageIn() {
- return messageStyleRaw(false, false);
- }
- MessageStyle &ChatStyle::messageInSelected() {
- return messageStyleRaw(false, true);
- }
- MessageStyle &ChatStyle::messageOut() {
- return messageStyleRaw(true, false);
- }
- MessageStyle &ChatStyle::messageOutSelected() {
- return messageStyleRaw(true, true);
- }
- MessageImageStyle &ChatStyle::imageStyleRaw(bool selected) const {
- return _imageStyles[selected ? 1 : 0];
- }
- MessageImageStyle &ChatStyle::image() {
- return imageStyleRaw(false);
- }
- MessageImageStyle &ChatStyle::imageSelected() {
- return imageStyleRaw(true);
- }
- void ChatStyle::make(style::color &my, const style::color &original) const {
- my = _colors[style::main_palette::indexOfColor(original)];
- }
- void ChatStyle::make(style::icon &my, const style::icon &original) const {
- my = original.withPalette(*this);
- }
- void ChatStyle::make(
- style::TextPalette &my,
- const style::TextPalette &original) const {
- my.linkAlwaysActive = original.linkAlwaysActive;
- make(my.linkFg, original.linkFg);
- make(my.monoFg, original.monoFg);
- make(my.spoilerFg, original.spoilerFg);
- make(my.selectBg, original.selectBg);
- make(my.selectFg, original.selectFg);
- make(my.selectLinkFg, original.selectLinkFg);
- make(my.selectMonoFg, original.selectMonoFg);
- make(my.selectSpoilerFg, original.selectSpoilerFg);
- make(my.selectOverlay, original.selectOverlay);
- }
- void ChatStyle::make(
- style::TwoIconButton &my,
- const style::TwoIconButton &original) const {
- my = original;
- make(my.iconBelow, original.iconBelow);
- make(my.iconAbove, original.iconAbove);
- make(my.iconBelowOver, original.iconBelowOver);
- make(my.iconAboveOver, original.iconAboveOver);
- make(my.ripple.color, original.ripple.color);
- }
- void ChatStyle::make(
- style::ScrollArea &my,
- const style::ScrollArea &original) const {
- my = original;
- make(my.bg, original.bg);
- make(my.bgOver, original.bgOver);
- make(my.barBg, original.barBg);
- make(my.barBgOver, original.barBgOver);
- make(my.shColor, original.shColor);
- }
- template <typename Type>
- void ChatStyle::make(
- Type MessageStyle::*my,
- const Type &originalIn,
- const Type &originalInSelected,
- const Type &originalOut,
- const Type &originalOutSelected) {
- make(messageIn().*my, originalIn);
- make(messageInSelected().*my, originalInSelected);
- make(messageOut().*my, originalOut);
- make(messageOutSelected().*my, originalOutSelected);
- }
- template <typename Type>
- void ChatStyle::make(
- Type MessageImageStyle::*my,
- const Type &original,
- const Type &originalSelected) {
- make(image().*my, original);
- make(imageSelected().*my, originalSelected);
- }
- uint8 DecideColorIndex(uint64 id) {
- return id % kSimpleColorIndexCount;
- }
- uint8 ColorIndexToPaletteIndex(uint8 colorIndex) {
- Expects(colorIndex >= 0 && colorIndex < kColorIndexCount);
- const int8 map[] = { 0, 7, 4, 1, 6, 3, 5 };
- return map[colorIndex % kSimpleColorIndexCount];
- }
- QColor FromNameFg(
- not_null<const ChatStyle*> st,
- bool selected,
- uint8 colorIndex) {
- return st->coloredValues(selected, colorIndex).name;
- }
- void FillComplexOverlayRect(
- QPainter &p,
- QRect rect,
- const style::color &color,
- const CornersPixmaps &corners) {
- using namespace Images;
- const auto pix = corners.p;
- const auto fillRect = [&](QRect rect) {
- p.fillRect(rect, color);
- };
- if (pix[kTopLeft].isNull()
- && pix[kTopRight].isNull()
- && pix[kBottomLeft].isNull()
- && pix[kBottomRight].isNull()) {
- fillRect(rect);
- return;
- }
- const auto ratio = style::DevicePixelRatio();
- const auto fillCorner = [&](int left, int top, int index) {
- p.drawPixmap(left, top, pix[index]);
- };
- const auto cornerSize = [&](int index) {
- const auto &p = pix[index];
- return p.isNull() ? 0 : p.width() / ratio;
- };
- const auto verticalSkip = [&](int left, int right) {
- return std::max(cornerSize(left), cornerSize(right));
- };
- const auto top = verticalSkip(kTopLeft, kTopRight);
- const auto bottom = verticalSkip(kBottomLeft, kBottomRight);
- if (top) {
- const auto left = cornerSize(kTopLeft);
- const auto right = cornerSize(kTopRight);
- if (left) {
- fillCorner(rect.left(), rect.top(), kTopLeft);
- if (const auto add = top - left) {
- fillRect({ rect.left(), rect.top() + left, left, add });
- }
- }
- if (const auto fill = rect.width() - left - right; fill > 0) {
- fillRect({ rect.left() + left, rect.top(), fill, top });
- }
- if (right) {
- fillCorner(
- rect.left() + rect.width() - right,
- rect.top(),
- kTopRight);
- if (const auto add = top - right) {
- fillRect({
- rect.left() + rect.width() - right,
- rect.top() + right,
- right,
- add,
- });
- }
- }
- }
- if (const auto h = rect.height() - top - bottom; h > 0) {
- fillRect({ rect.left(), rect.top() + top, rect.width(), h });
- }
- if (bottom) {
- const auto left = cornerSize(kBottomLeft);
- const auto right = cornerSize(kBottomRight);
- if (left) {
- fillCorner(
- rect.left(),
- rect.top() + rect.height() - left,
- kBottomLeft);
- if (const auto add = bottom - left) {
- fillRect({
- rect.left(),
- rect.top() + rect.height() - bottom,
- left,
- add,
- });
- }
- }
- if (const auto fill = rect.width() - left - right; fill > 0) {
- fillRect({
- rect.left() + left,
- rect.top() + rect.height() - bottom,
- fill,
- bottom,
- });
- }
- if (right) {
- fillCorner(
- rect.left() + rect.width() - right,
- rect.top() + rect.height() - right,
- kBottomRight);
- if (const auto add = bottom - right) {
- fillRect({
- rect.left() + rect.width() - right,
- rect.top() + rect.height() - bottom,
- right,
- add,
- });
- }
- }
- }
- }
- void FillComplexEllipse(
- QPainter &p,
- not_null<const ChatStyle*> st,
- QRect rect) {
- PainterHighQualityEnabler hq(p);
- p.setPen(Qt::NoPen);
- p.setBrush(st->msgSelectOverlay());
- p.drawEllipse(rect);
- }
- } // namespace Ui
|