Added initial implementation of gradient color editor.
This commit is contained in:
		
							parent
							
								
									16f59eee5d
								
							
						
					
					
						commit
						a61c4f1813
					
				
					 5 changed files with 361 additions and 1 deletions
				
			
		| 
						 | 
					@ -857,6 +857,8 @@ PRIVATE
 | 
				
			||||||
    info/profile/info_profile_widget.h
 | 
					    info/profile/info_profile_widget.h
 | 
				
			||||||
    info/settings/info_settings_widget.cpp
 | 
					    info/settings/info_settings_widget.cpp
 | 
				
			||||||
    info/settings/info_settings_widget.h
 | 
					    info/settings/info_settings_widget.h
 | 
				
			||||||
 | 
					    info/userpic/info_userpic_colors_editor.cpp
 | 
				
			||||||
 | 
					    info/userpic/info_userpic_colors_editor.h
 | 
				
			||||||
    info/userpic/info_userpic_emoji_builder.cpp
 | 
					    info/userpic/info_userpic_emoji_builder.cpp
 | 
				
			||||||
    info/userpic/info_userpic_emoji_builder.h
 | 
					    info/userpic/info_userpic_emoji_builder.h
 | 
				
			||||||
    info/userpic/info_userpic_emoji_builder_common.cpp
 | 
					    info/userpic/info_userpic_emoji_builder_common.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,25 @@ userpicBuilderEmojiLayerMinHeight: 496px;
 | 
				
			||||||
userpicBuilderEmojiSelectorMinHeight: 216px;
 | 
					userpicBuilderEmojiSelectorMinHeight: 216px;
 | 
				
			||||||
userpicBuilderEmojiSelectorTogglePosition: point(6px, 6px);
 | 
					userpicBuilderEmojiSelectorTogglePosition: point(6px, 6px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					userpicBuilderEmojiColorMinus: IconButton(defaultIconButton) {
 | 
				
			||||||
 | 
						width: userpicBuilderEmojiAccentColorSize;
 | 
				
			||||||
 | 
						height: userpicBuilderEmojiAccentColorSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						icon: icon {{ "settings/minus", menuIconFg }};
 | 
				
			||||||
 | 
						iconOver: icon {{ "settings/minus", menuIconFg }};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rippleAreaSize: userpicBuilderEmojiAccentColorSize;
 | 
				
			||||||
 | 
						rippleAreaPosition: point(0px, 0px);
 | 
				
			||||||
 | 
						ripple: universalRippleAnimation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					userpicBuilderEmojiColorPlus: IconButton(userpicBuilderEmojiColorMinus) {
 | 
				
			||||||
 | 
						icon: icon {{ "settings/plus", menuIconFg }};
 | 
				
			||||||
 | 
						iconOver: icon {{ "settings/plus", menuIconFg }};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
userpicBuilderEmojiToggleEmojiIcon: icon {{ "chat/input_smile_face", emojiIconFg }};
 | 
					userpicBuilderEmojiToggleEmojiIcon: icon {{ "chat/input_smile_face", emojiIconFg }};
 | 
				
			||||||
userpicBuilderEmojiToggleEmojiSize: 18px;
 | 
					userpicBuilderEmojiToggleEmojiSize: 18px;
 | 
				
			||||||
userpicBuilderEmojiToggleStickersIcon: icon {{ "menu/stickers", emojiIconFg }};
 | 
					userpicBuilderEmojiToggleStickersIcon: icon {{ "menu/stickers", emojiIconFg }};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					userpicBuilderEmojiSlideDuration: 120;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										309
									
								
								Telegram/SourceFiles/info/userpic/info_userpic_colors_editor.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								Telegram/SourceFiles/info/userpic/info_userpic_colors_editor.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,309 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					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 "info/userpic/info_userpic_colors_editor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "base/random.h"
 | 
				
			||||||
 | 
					#include "ui/wrap/fade_wrap.h"
 | 
				
			||||||
 | 
					#include "info/userpic/info_userpic_emoji_builder_preview.h"
 | 
				
			||||||
 | 
					#include "info/userpic/info_userpic_color_circle_button.h"
 | 
				
			||||||
 | 
					#include "info/userpic/info_userpic_emoji_builder_common.h"
 | 
				
			||||||
 | 
					#include "ui/wrap/vertical_layout.h"
 | 
				
			||||||
 | 
					#include "ui/widgets/color_editor.h"
 | 
				
			||||||
 | 
					#include "ui/wrap/padding_wrap.h"
 | 
				
			||||||
 | 
					#include "settings/settings_common.h"
 | 
				
			||||||
 | 
					#include "ui/widgets/buttons.h"
 | 
				
			||||||
 | 
					#include "ui/rect.h"
 | 
				
			||||||
 | 
					#include "styles/style_info_userpic_builder.h"
 | 
				
			||||||
 | 
					#include "styles/style_boxes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace UserpicBuilder {
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr auto kMaxColors = int(4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] QColor RandomColor(const QColor &c) {
 | 
				
			||||||
 | 
						auto random = bytes::vector(2);
 | 
				
			||||||
 | 
						base::RandomFill(random.data(), random.size());
 | 
				
			||||||
 | 
						auto result = QColor();
 | 
				
			||||||
 | 
						result.setHslF(
 | 
				
			||||||
 | 
							(uchar(random[0]) % 100) / 100.,
 | 
				
			||||||
 | 
							(uchar(random[1]) % 50) / 100. + 0.5,
 | 
				
			||||||
 | 
							c.lightnessF());
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ColorsLine final : public Ui::RpWidget {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						using Chosen = CircleButton;
 | 
				
			||||||
 | 
						using Success = bool;
 | 
				
			||||||
 | 
						ColorsLine(
 | 
				
			||||||
 | 
							not_null<Ui::RpWidget*> parent,
 | 
				
			||||||
 | 
							not_null<std::vector<QColor>*> colors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void init();
 | 
				
			||||||
 | 
						void fillButtons();
 | 
				
			||||||
 | 
						Success addColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] Chosen *chosen() const;
 | 
				
			||||||
 | 
						[[nodiscard]] rpl::producer<Chosen*> chosenChanges() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						struct ButtonState {
 | 
				
			||||||
 | 
							bool shown = false;
 | 
				
			||||||
 | 
							int left = 0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						[[nodiscard]] std::vector<ButtonState> calculatePositionFor(int count);
 | 
				
			||||||
 | 
						void processChange(
 | 
				
			||||||
 | 
							const std::vector<QColor> wasColors,
 | 
				
			||||||
 | 
							const std::vector<QColor> nowColors);
 | 
				
			||||||
 | 
						void setLastChosen() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const not_null<std::vector<QColor>*> _colors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base::unique_qptr<Ui::RpWidget> _container;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<not_null<CircleButton*>> _colorButtons;
 | 
				
			||||||
 | 
						std::vector<not_null<Ui::FadeWrap<Ui::RpWidget>*>> _wraps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Ui::Animations::Simple _chooseAnimation;
 | 
				
			||||||
 | 
						Ui::Animations::Simple _positionAnimation;
 | 
				
			||||||
 | 
						Chosen *_chosen = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rpl::event_stream<Chosen*> _chosenChanges;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ColorsLine::ColorsLine(
 | 
				
			||||||
 | 
						not_null<Ui::RpWidget*> parent,
 | 
				
			||||||
 | 
						not_null<std::vector<QColor>*> colors)
 | 
				
			||||||
 | 
					: Ui::RpWidget(parent)
 | 
				
			||||||
 | 
					, _colors(colors) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ColorsLine::init() {
 | 
				
			||||||
 | 
						fillButtons();
 | 
				
			||||||
 | 
						processChange(*_colors, *_colors);
 | 
				
			||||||
 | 
						setLastChosen();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ColorsLine::Success ColorsLine::addColor() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ColorsLine::fillButtons() {
 | 
				
			||||||
 | 
						_container = base::make_unique_q<Ui::RpWidget>(this);
 | 
				
			||||||
 | 
						const auto container = _container.get();
 | 
				
			||||||
 | 
						sizeValue(
 | 
				
			||||||
 | 
						) | rpl::start_with_next([=](const QSize &s) {
 | 
				
			||||||
 | 
							container->setGeometry(Rect(s));
 | 
				
			||||||
 | 
						}, container->lifetime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto minus = Ui::CreateChild<Ui::FadeWrap<Ui::IconButton>>(
 | 
				
			||||||
 | 
							container,
 | 
				
			||||||
 | 
							object_ptr<Ui::IconButton>(
 | 
				
			||||||
 | 
								container,
 | 
				
			||||||
 | 
								st::userpicBuilderEmojiColorMinus));
 | 
				
			||||||
 | 
						_wraps.push_back(minus);
 | 
				
			||||||
 | 
						minus->entity()->setClickedCallback([=] {
 | 
				
			||||||
 | 
							const auto wasColors = *_colors;
 | 
				
			||||||
 | 
							_colors->erase(_colors->end() - 1);
 | 
				
			||||||
 | 
							const auto nowColors = *_colors;
 | 
				
			||||||
 | 
							processChange(wasColors, nowColors);
 | 
				
			||||||
 | 
							setLastChosen();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (auto i = 0; i < kMaxColors; i++) {
 | 
				
			||||||
 | 
							const auto wrap = Ui::CreateChild<Ui::FadeWrap<CircleButton>>(
 | 
				
			||||||
 | 
								container,
 | 
				
			||||||
 | 
								object_ptr<CircleButton>(container));
 | 
				
			||||||
 | 
							const auto button = wrap->entity();
 | 
				
			||||||
 | 
							button->resize(height(), height());
 | 
				
			||||||
 | 
							button->setIndex(i);
 | 
				
			||||||
 | 
							_wraps.push_back(wrap);
 | 
				
			||||||
 | 
							_colorButtons.push_back(button);
 | 
				
			||||||
 | 
							button->setClickedCallback([=] {
 | 
				
			||||||
 | 
								const auto wasChosen = _chosen;
 | 
				
			||||||
 | 
								_chosen = button;
 | 
				
			||||||
 | 
								const auto nowChosen = _chosen;
 | 
				
			||||||
 | 
								_chosenChanges.fire_copy(_chosen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								_chooseAnimation.stop();
 | 
				
			||||||
 | 
								_chooseAnimation.start([=](float64 progress) {
 | 
				
			||||||
 | 
									if (wasChosen) {
 | 
				
			||||||
 | 
										wasChosen->setSelectedProgress(1. - progress);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									nowChosen->setSelectedProgress(progress);
 | 
				
			||||||
 | 
								}, 0., 1., st::userpicBuilderEmojiSlideDuration);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							if (i < _colors->size()) {
 | 
				
			||||||
 | 
								button->setBrush((*_colors)[i]);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								wrap->hide(anim::type::instant);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto plus = Ui::CreateChild<Ui::FadeWrap<Ui::IconButton>>(
 | 
				
			||||||
 | 
							container,
 | 
				
			||||||
 | 
							object_ptr<Ui::IconButton>(
 | 
				
			||||||
 | 
								container,
 | 
				
			||||||
 | 
								st::userpicBuilderEmojiColorPlus));
 | 
				
			||||||
 | 
						_wraps.push_back(plus);
 | 
				
			||||||
 | 
						plus->entity()->setClickedCallback([=] {
 | 
				
			||||||
 | 
							const auto wasColors = *_colors;
 | 
				
			||||||
 | 
							_colors->push_back(RandomColor(_colors->back()));
 | 
				
			||||||
 | 
							const auto nowColors = *_colors;
 | 
				
			||||||
 | 
							processChange(wasColors, nowColors);
 | 
				
			||||||
 | 
							setLastChosen();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						for (const auto &wrap : _wraps) {
 | 
				
			||||||
 | 
							wrap->setDuration(st::userpicBuilderEmojiSlideDuration);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<ColorsLine::ButtonState> ColorsLine::calculatePositionFor(
 | 
				
			||||||
 | 
							int count) {
 | 
				
			||||||
 | 
						// Minus - Color - Color - Color - Color - Plus.
 | 
				
			||||||
 | 
						auto result = std::vector<ButtonState>(6);
 | 
				
			||||||
 | 
						const auto fullWidth = _container->width();
 | 
				
			||||||
 | 
						const auto width = _container->height();
 | 
				
			||||||
 | 
						const auto colorsWidth = width * count + width * (count - 1);
 | 
				
			||||||
 | 
						const auto left = (fullWidth - colorsWidth) / 2;
 | 
				
			||||||
 | 
						for (auto i = 0; i < _colorButtons.size(); i++) {
 | 
				
			||||||
 | 
							result[i + 1] = {
 | 
				
			||||||
 | 
								.shown = (i < count),
 | 
				
			||||||
 | 
								.left = left + (i * width * 2),
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result[0] = {
 | 
				
			||||||
 | 
							.shown = (count > 1),
 | 
				
			||||||
 | 
							.left = (left - width * 2),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						result[result.size() - 1] = {
 | 
				
			||||||
 | 
							.shown = (count < kMaxColors),
 | 
				
			||||||
 | 
							.left = (left + colorsWidth + width),
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ColorsLine::processChange(
 | 
				
			||||||
 | 
							const std::vector<QColor> wasColors,
 | 
				
			||||||
 | 
							const std::vector<QColor> nowColors) {
 | 
				
			||||||
 | 
						const auto wasPosition = calculatePositionFor(wasColors.size());
 | 
				
			||||||
 | 
						const auto nowPosition = calculatePositionFor(nowColors.size());
 | 
				
			||||||
 | 
						for (auto i = 0; i < nowPosition.size(); i++) {
 | 
				
			||||||
 | 
							const auto colorIndex = i - 1;
 | 
				
			||||||
 | 
							if ((colorIndex > 0) && (colorIndex < _colors->size())) {
 | 
				
			||||||
 | 
								_colorButtons[colorIndex]->setBrush((*_colors)[colorIndex]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_wraps[i]->toggle(nowPosition[i].shown, anim::type::normal);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_positionAnimation.stop();
 | 
				
			||||||
 | 
						_positionAnimation.start([=](float64 value) {
 | 
				
			||||||
 | 
							for (auto i = 0; i < nowPosition.size(); i++) {
 | 
				
			||||||
 | 
								const auto wasLeft = wasPosition[i].left;
 | 
				
			||||||
 | 
								const auto nowLeft = nowPosition[i].left;
 | 
				
			||||||
 | 
								const auto left = anim::interpolate(wasLeft, nowLeft, value);
 | 
				
			||||||
 | 
								_wraps[i]->moveToLeft(left, 0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}, 0., 1., st::userpicBuilderEmojiSlideDuration);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ColorsLine::setLastChosen() const {
 | 
				
			||||||
 | 
						for (auto i = 0; i < _colorButtons.size(); i++) {
 | 
				
			||||||
 | 
							if (i == (_colors->size() - 1)) {
 | 
				
			||||||
 | 
								_colorButtons[i]->clicked({}, Qt::LeftButton);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ColorsLine::Chosen *ColorsLine::chosen() const {
 | 
				
			||||||
 | 
						return _chosen;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rpl::producer<ColorsLine::Chosen*> ColorsLine::chosenChanges() const {
 | 
				
			||||||
 | 
						return _chosenChanges.events();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object_ptr<Ui::RpWidget> CreateGradientEditor(
 | 
				
			||||||
 | 
							not_null<Ui::RpWidget*> parent,
 | 
				
			||||||
 | 
							DocumentData *document,
 | 
				
			||||||
 | 
							std::vector<QColor> startColors,
 | 
				
			||||||
 | 
							BothWayCommunication<std::vector<QColor>> communication) {
 | 
				
			||||||
 | 
						auto container = object_ptr<Ui::VerticalLayout>(parent.get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct State {
 | 
				
			||||||
 | 
							std::vector<QColor> colors;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto preview = container->add(
 | 
				
			||||||
 | 
							object_ptr<Ui::CenterWrap<EmojiUserpic>>(
 | 
				
			||||||
 | 
								container,
 | 
				
			||||||
 | 
								object_ptr<EmojiUserpic>(
 | 
				
			||||||
 | 
									container,
 | 
				
			||||||
 | 
									Size(st::defaultUserpicButton.photoSize))))->entity();
 | 
				
			||||||
 | 
						preview->setDuration(0);
 | 
				
			||||||
 | 
						if (document) {
 | 
				
			||||||
 | 
							preview->setDocument(document);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Settings::AddSkip(container);
 | 
				
			||||||
 | 
						Settings::AddDivider(container);
 | 
				
			||||||
 | 
						Settings::AddSkip(container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto state = container->lifetime().make_state<State>();
 | 
				
			||||||
 | 
						state->colors = std::move(startColors);
 | 
				
			||||||
 | 
						const auto buttonsContainer = container->add(object_ptr<ColorsLine>(
 | 
				
			||||||
 | 
							container,
 | 
				
			||||||
 | 
							&state->colors));
 | 
				
			||||||
 | 
						buttonsContainer->resize(0, st::userpicBuilderEmojiAccentColorSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Settings::AddSkip(container);
 | 
				
			||||||
 | 
						Settings::AddDivider(container);
 | 
				
			||||||
 | 
						Settings::AddSkip(container);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto editor = container->add(object_ptr<ColorEditor>(
 | 
				
			||||||
 | 
							container,
 | 
				
			||||||
 | 
							ColorEditor::Mode::HSL,
 | 
				
			||||||
 | 
							state->colors.back()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buttonsContainer->chosenChanges(
 | 
				
			||||||
 | 
						) | rpl::start_with_next([=](ColorsLine::Chosen *chosen) {
 | 
				
			||||||
 | 
							if (chosen) {
 | 
				
			||||||
 | 
								editor->showColor(state->colors[chosen->index()]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}, editor->lifetime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const auto save = crl::guard(container.data(), [=] {
 | 
				
			||||||
 | 
							communication.result(state->colors);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						// editor->submitRequests(
 | 
				
			||||||
 | 
						// ) | rpl::start_with_next([=] {
 | 
				
			||||||
 | 
						// }, editor->lifetime());
 | 
				
			||||||
 | 
						editor->colorValue(
 | 
				
			||||||
 | 
						) | rpl::start_with_next([=](QColor c) {
 | 
				
			||||||
 | 
							if (const auto chosen = buttonsContainer->chosen()) {
 | 
				
			||||||
 | 
								chosen->setBrush(c);
 | 
				
			||||||
 | 
								state->colors[chosen->index()] = c;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							preview->setGradientColors(state->colors);
 | 
				
			||||||
 | 
						}, preview->lifetime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						base::take(
 | 
				
			||||||
 | 
							communication.triggers
 | 
				
			||||||
 | 
						) | rpl::start_with_next([=] {
 | 
				
			||||||
 | 
							save();
 | 
				
			||||||
 | 
						}, container->lifetime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						container->resizeToWidth(editor->width());
 | 
				
			||||||
 | 
						buttonsContainer->init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return container;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace UserpicBuilder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Object>
 | 
				
			||||||
 | 
					class object_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DocumentData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Ui {
 | 
				
			||||||
 | 
					class RpWidget;
 | 
				
			||||||
 | 
					} // namespace Ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace UserpicBuilder {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Result>
 | 
				
			||||||
 | 
					struct BothWayCommunication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] object_ptr<Ui::RpWidget> CreateGradientEditor(
 | 
				
			||||||
 | 
						not_null<Ui::RpWidget*> parent,
 | 
				
			||||||
 | 
						DocumentData *document,
 | 
				
			||||||
 | 
						std::vector<QColor> startColors,
 | 
				
			||||||
 | 
						BothWayCommunication<std::vector<QColor>> communication);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace UserpicBuilder
 | 
				
			||||||
| 
						 | 
					@ -327,7 +327,7 @@ not_null<Ui::VerticalLayout*> CreateUserpicBuilder(
 | 
				
			||||||
							1. - progress);
 | 
												1. - progress);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					state->circleButtons[now]->setSelectedProgress(progress);
 | 
										state->circleButtons[now]->setSelectedProgress(progress);
 | 
				
			||||||
				}, 0., 1., st::slideDuration);
 | 
									}, 0., 1., st::userpicBuilderEmojiSlideDuration);
 | 
				
			||||||
				state->colorIndex = now;
 | 
									state->colorIndex = now;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				preview->setGradientColors(colors);
 | 
									preview->setGradientColors(colors);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue