diff --git a/Telegram/SourceFiles/info/userpic/info_userpic_emoji_builder_widget.cpp b/Telegram/SourceFiles/info/userpic/info_userpic_emoji_builder_widget.cpp index fdca30ba1f..8012f8cffe 100644 --- a/Telegram/SourceFiles/info/userpic/info_userpic_emoji_builder_widget.cpp +++ b/Telegram/SourceFiles/info/userpic/info_userpic_emoji_builder_widget.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "chat_helpers/emoji_list_widget.h" #include "chat_helpers/stickers_list_widget.h" +#include "data/data_document.h" #include "data/data_message_reactions.h" #include "data/data_session.h" #include "data/stickers/data_custom_emoji.h" @@ -62,6 +63,39 @@ void AlignChildren(not_null widget, int fullWidth) { } } +[[nodiscard]] QImage GenerateSpecial( + int size, + const std::vector colors) { + if (colors.empty()) { + auto image = QImage( + Size(size * style::DevicePixelRatio()), + QImage::Format_ARGB32_Premultiplied); + image.setDevicePixelRatio(style::DevicePixelRatio()); + image.fill(Qt::transparent); + { + auto p = QPainter(&image); + st::userpicBuilderEmojiColorPlus.icon.paintInCenter( + p, + Rect(Size(size))); + } + return image; + } else { + auto image = GenerateGradient(Size(size), colors); + { + auto p = QPainter(&image); + constexpr auto kEllipseSize = 1; + const auto center = QPointF(size / 2., size / 2.); + const auto shift = QPointF(kEllipseSize * 4, 0); + p.setPen(Qt::NoPen); + p.setBrush(st::boxBg); + p.drawEllipse(center, kEllipseSize, kEllipseSize); + p.drawEllipse(center + shift, kEllipseSize, kEllipseSize); + p.drawEllipse(center - shift, kEllipseSize, kEllipseSize); + } + return image; + } +} + [[nodiscard]] std::vector ColorsByIndex(int index) { const auto c = Ui::EmptyUserpic::UserpicColor( Ui::EmptyUserpic::ColorIndex(index)); @@ -310,6 +344,9 @@ not_null CreateUserpicBuilder( std::vector> circleButtons; Ui::Animations::Simple chosenColorAnimation; int colorIndex = -1; + + std::vector editorColors; + StartData gradientEditorStartData; }; const auto state = container->lifetime().make_state(); @@ -339,21 +376,50 @@ not_null CreateUserpicBuilder( container, st::userpicBuilderEmojiBubblePaletteSize, [=] { return controller->chatStyle(); }); - const auto palette = Ui::CreateChild(paletteBg.get()); { constexpr auto kColorsCount = int(7); + const auto checkIsSpecial = [=](int i) { + return (i == kColorsCount); + }; const auto size = st::userpicBuilderEmojiAccentColorSize; - for (auto i = 0; i < kColorsCount; i++) { + for (auto i = 0; i < kColorsCount + 1; i++) { + const auto isSpecial = checkIsSpecial(i); const auto colors = ColorsByIndex(i); const auto button = Ui::CreateChild(palette); state->circleButtons.push_back(button); button->resize(size, size); - button->setBrush(GenerateGradient(Size(size), colors)); + button->setBrush(isSpecial + ? GenerateSpecial(size, state->editorColors) + : GenerateGradient(Size(size), colors)); + + const auto openEditor = isSpecial + ? Fn([=] { + if (checkIsSpecial(state->colorIndex)) { + state->colorIndex = -1; + } + ShowGradientEditor( + controller, + state->gradientEditorStartData, + [=](std::vector colors) { + state->editorColors = std::move(colors); + button->setBrush( + GenerateSpecial(size, state->editorColors)); + button->clicked({}, Qt::LeftButton); + }); + }) + : nullptr; + button->setClickedCallback([=] { + if (openEditor && state->editorColors.empty()) { + return openEditor(); + } const auto was = state->colorIndex; const auto now = i; if (was == now) { + if (openEditor) { + openEditor(); + } return; } state->chosenColorAnimation.stop(); @@ -366,7 +432,11 @@ not_null CreateUserpicBuilder( }, 0., 1., st::userpicBuilderEmojiSlideDuration); state->colorIndex = now; - preview->setGradientColors(colors); + const auto result = isSpecial + ? state->editorColors + : colors; + state->gradientEditorStartData.gradientEditorColors = result; + preview->setGradientColors(result); }); } const auto current = data.builderColorIndex % kColorsCount; @@ -399,6 +469,7 @@ not_null CreateUserpicBuilder( controller); selector->chosen( ) | rpl::start_with_next([=](not_null document) { + state->gradientEditorStartData.documentId = document->id; preview->setDocument(document); }, preview->lifetime()); selectorBg->innerRectValue(