"Fossies" - the Fresh Open Source Software Archive 
Member "tdesktop-2.6.1/Telegram/SourceFiles/ui/chat/pinned_bar.cpp" (24 Feb 2021, 5255 Bytes) of package /linux/misc/tdesktop-2.6.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "pinned_bar.cpp" see the
Fossies "Dox" file reference documentation.
1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "ui/chat/pinned_bar.h"
9
10 #include "ui/chat/message_bar.h"
11 #include "ui/widgets/shadow.h"
12 #include "ui/widgets/buttons.h"
13 #include "styles/style_chat.h"
14 #include "styles/palette.h"
15
16 #include <QtGui/QtEvents>
17
18 namespace Ui {
19
20 PinnedBar::PinnedBar(
21 not_null<QWidget*> parent,
22 rpl::producer<MessageBarContent> content)
23 : _wrap(parent, object_ptr<RpWidget>(parent))
24 , _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget())) {
25 _wrap.hide(anim::type::instant);
26 _shadow->hide();
27
28 _wrap.entity()->paintRequest(
29 ) | rpl::start_with_next([=](QRect clip) {
30 QPainter(_wrap.entity()).fillRect(clip, st::historyPinnedBg);
31 }, lifetime());
32 _wrap.setAttribute(Qt::WA_OpaquePaintEvent);
33
34 auto copy = std::move(
35 content
36 ) | rpl::start_spawning(_wrap.lifetime());
37
38 rpl::duplicate(
39 copy
40 ) | rpl::filter([=](const MessageBarContent &content) {
41 return !content.title.isEmpty() || !content.text.text.isEmpty();
42 }) | rpl::start_with_next([=](MessageBarContent &&content) {
43 const auto creating = !_bar;
44 if (creating) {
45 createControls();
46 }
47 _bar->set(std::move(content));
48 if (creating) {
49 _bar->finishAnimating();
50 }
51 }, lifetime());
52
53 std::move(
54 copy
55 ) | rpl::map([=](const MessageBarContent &content) {
56 return content.title.isEmpty() || content.text.text.isEmpty();
57 }) | rpl::start_with_next_done([=](bool hidden) {
58 _shouldBeShown = !hidden;
59 if (!_forceHidden) {
60 _wrap.toggle(_shouldBeShown, anim::type::normal);
61 } else if (!_shouldBeShown) {
62 _bar = nullptr;
63 }
64 }, [=] {
65 _forceHidden = true;
66 _wrap.toggle(false, anim::type::normal);
67 }, lifetime());
68 }
69
70 PinnedBar::~PinnedBar() {
71 _rightButton.destroy();
72 }
73
74 void PinnedBar::setRightButton(object_ptr<Ui::RpWidget> button) {
75 _rightButton.destroy();
76 _rightButton = std::move(button);
77 if (_rightButton) {
78 _rightButton->setParent(_wrap.entity());
79 _rightButton->show();
80 }
81 if (_bar) {
82 updateControlsGeometry(_wrap.geometry());
83 }
84 }
85
86 void PinnedBar::updateControlsGeometry(QRect wrapGeometry) {
87 _bar->widget()->resizeToWidth(
88 wrapGeometry.width() - (_rightButton ? _rightButton->width() : 0));
89 const auto hidden = _wrap.isHidden() || !wrapGeometry.height();
90 if (_shadow->isHidden() != hidden) {
91 _shadow->setVisible(!hidden);
92 }
93 if (_rightButton) {
94 _rightButton->moveToRight(0, 0);
95 }
96 }
97
98 void PinnedBar::setShadowGeometryPostprocess(Fn<QRect(QRect)> postprocess) {
99 _shadowGeometryPostprocess = std::move(postprocess);
100 updateShadowGeometry(_wrap.geometry());
101 }
102
103 void PinnedBar::updateShadowGeometry(QRect wrapGeometry) {
104 const auto regular = QRect(
105 wrapGeometry.x(),
106 wrapGeometry.y() + wrapGeometry.height(),
107 wrapGeometry.width(),
108 st::lineWidth);
109 _shadow->setGeometry(_shadowGeometryPostprocess
110 ? _shadowGeometryPostprocess(regular)
111 : regular);
112 }
113
114 void PinnedBar::createControls() {
115 Expects(!_bar);
116
117 _bar = std::make_unique<MessageBar>(
118 _wrap.entity(),
119 st::defaultMessageBar);
120 if (_rightButton) {
121 _rightButton->raise();
122 }
123
124 // Clicks.
125 _bar->widget()->setCursor(style::cur_pointer);
126 _bar->widget()->events(
127 ) | rpl::filter([=](not_null<QEvent*> event) {
128 return (event->type() == QEvent::MouseButtonPress);
129 }) | rpl::map([=] {
130 return _bar->widget()->events(
131 ) | rpl::filter([=](not_null<QEvent*> event) {
132 return (event->type() == QEvent::MouseButtonRelease);
133 }) | rpl::take(1) | rpl::filter([=](not_null<QEvent*> event) {
134 return _bar->widget()->rect().contains(
135 static_cast<QMouseEvent*>(event.get())->pos());
136 });
137 }) | rpl::flatten_latest(
138 ) | rpl::map([] {
139 return rpl::empty_value();
140 }) | rpl::start_to_stream(_barClicks, _bar->widget()->lifetime());
141
142 _bar->widget()->move(0, 0);
143 _bar->widget()->show();
144 _wrap.entity()->resize(_wrap.entity()->width(), _bar->widget()->height());
145
146 _wrap.geometryValue(
147 ) | rpl::start_with_next([=](QRect rect) {
148 updateShadowGeometry(rect);
149 updateControlsGeometry(rect);
150 }, _bar->widget()->lifetime());
151
152 _wrap.shownValue(
153 ) | rpl::skip(
154 1
155 ) | rpl::filter([=](bool shown) {
156 return !shown && !_forceHidden;
157 }) | rpl::start_with_next([=] {
158 _bar = nullptr;
159 }, _bar->widget()->lifetime());
160
161 Ensures(_bar != nullptr);
162 }
163
164 void PinnedBar::show() {
165 if (!_forceHidden) {
166 return;
167 }
168 _forceHidden = false;
169 if (_shouldBeShown) {
170 _wrap.show(anim::type::instant);
171 _shadow->show();
172 }
173 }
174
175 void PinnedBar::hide() {
176 if (_forceHidden) {
177 return;
178 }
179 _forceHidden = true;
180 _wrap.hide(anim::type::instant);
181 _shadow->hide();
182 }
183
184 void PinnedBar::raise() {
185 _wrap.raise();
186 _shadow->raise();
187 }
188
189 void PinnedBar::finishAnimating() {
190 _wrap.finishAnimating();
191 }
192
193 void PinnedBar::move(int x, int y) {
194 _wrap.move(x, y);
195 }
196
197 void PinnedBar::resizeToWidth(int width) {
198 _wrap.entity()->resizeToWidth(width);
199 }
200
201 int PinnedBar::height() const {
202 return !_forceHidden
203 ? _wrap.height()
204 : _shouldBeShown
205 ? st::historyReplyHeight
206 : 0;
207 }
208
209 rpl::producer<int> PinnedBar::heightValue() const {
210 return _wrap.heightValue();
211 }
212
213 rpl::producer<> PinnedBar::barClicks() const {
214 return _barClicks.events();
215 }
216
217 } // namespace Ui