Moved PinnedBar to Ui:: in td_ui.
This commit is contained in:
parent
37fb94cbfb
commit
0873db58d0
8 changed files with 316 additions and 240 deletions
|
@ -92,6 +92,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/application.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "ui/chat/pinned_bar.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/item_text_options.h"
|
||||
#include "ui/unread_badge.h"
|
||||
|
@ -5252,10 +5253,9 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
messageId.type
|
||||
};
|
||||
});
|
||||
_pinnedBar = std::make_unique<HistoryView::PinnedBar>(
|
||||
_pinnedBar = std::make_unique<Ui::PinnedBar>(
|
||||
this,
|
||||
&session(),
|
||||
std::move(shown),
|
||||
HistoryView::PinnedBarContent(&session(), std::move(shown)),
|
||||
true);
|
||||
|
||||
_pinnedBar->closeClicks(
|
||||
|
|
|
@ -66,7 +66,7 @@ class SilentToggle;
|
|||
class FlatButton;
|
||||
class LinkButton;
|
||||
class RoundButton;
|
||||
class MessageBar;
|
||||
class PinnedBar;
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
|
@ -95,7 +95,6 @@ class TopBarWidget;
|
|||
class ContactStatus;
|
||||
class Element;
|
||||
class PinnedTracker;
|
||||
class PinnedBar;
|
||||
} // namespace HistoryView
|
||||
|
||||
class DragArea;
|
||||
|
@ -603,7 +602,7 @@ private:
|
|||
object_ptr<Ui::IconButton> _fieldBarCancel;
|
||||
|
||||
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
|
||||
std::unique_ptr<HistoryView::PinnedBar> _pinnedBar;
|
||||
std::unique_ptr<Ui::PinnedBar> _pinnedBar;
|
||||
int _pinnedBarHeight = 0;
|
||||
|
||||
mtpRequestId _saveEditMsgRequestId = 0;
|
||||
|
|
|
@ -12,42 +12,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_poll.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history.h"
|
||||
#include "apiwrap.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_history.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] Ui::MessageBarContent ContentWithoutPreview(
|
||||
not_null<HistoryItem*> item,
|
||||
PinnedIdType type) {
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto media = item->media();
|
||||
const auto poll = media ? media->poll() : nullptr;
|
||||
return Ui::MessageBarContent{
|
||||
.id = item->id,
|
||||
.title = ((type == PinnedIdType::First)
|
||||
? tr::lng_pinned_previous(tr::now) // #TODO pinned first?
|
||||
: (type == PinnedIdType::Middle)
|
||||
? tr::lng_pinned_previous(tr::now)
|
||||
: !poll
|
||||
? tr::lng_pinned_message(tr::now)
|
||||
: poll->quiz()
|
||||
? tr::lng_pinned_quiz(tr::now)
|
||||
: tr::lng_pinned_poll(tr::now)),
|
||||
.text = item->inReplyText(),
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] Ui::MessageBarContent ContentWithPreview(
|
||||
not_null<HistoryItem*> item,
|
||||
PinnedIdType type,
|
||||
Image *preview) {
|
||||
auto result = ContentWithoutPreview(item, type);
|
||||
auto result = ContentWithoutPreview(item);
|
||||
if (!preview) {
|
||||
static const auto kEmpty = [&] {
|
||||
const auto size = st::historyReplyHeight * cIntRetinaFactor();
|
||||
|
@ -66,15 +53,14 @@ namespace {
|
|||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
||||
not_null<HistoryItem*> item,
|
||||
PinnedIdType type) {
|
||||
not_null<HistoryItem*> item) {
|
||||
return item->history()->session().changes().messageFlagsValue(
|
||||
item,
|
||||
Data::MessageUpdate::Flag::Edited
|
||||
) | rpl::map([=]() -> rpl::producer<Ui::MessageBarContent> {
|
||||
const auto media = item->media();
|
||||
if (!media || !media->hasReplyPreview()) {
|
||||
return rpl::single(ContentWithoutPreview(item, type));
|
||||
return rpl::single(ContentWithoutPreview(item));
|
||||
}
|
||||
constexpr auto kFullLoaded = 2;
|
||||
constexpr auto kSomeLoaded = 1;
|
||||
|
@ -98,19 +84,19 @@ namespace {
|
|||
}) | rpl::then(
|
||||
rpl::single(kFullLoaded)
|
||||
) | rpl::map([=] {
|
||||
return ContentWithPreview(item, type, media->replyPreview());
|
||||
return ContentWithPreview(item, media->replyPreview());
|
||||
});
|
||||
}) | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
PinnedBarId id,
|
||||
FullMsgId id,
|
||||
bool alreadyLoaded = false) {
|
||||
if (!id.message) {
|
||||
if (!id) {
|
||||
return rpl::single(Ui::MessageBarContent());
|
||||
} else if (const auto item = session->data().message(id.message)) {
|
||||
return ContentByItem(item, id.type);
|
||||
} else if (const auto item = session->data().message(id)) {
|
||||
return ContentByItem(item);
|
||||
} else if (alreadyLoaded) {
|
||||
return rpl::single(Ui::MessageBarContent()); // Deleted message?..
|
||||
}
|
||||
|
@ -118,13 +104,13 @@ namespace {
|
|||
consumer.put_next(Ui::MessageBarContent{
|
||||
.text = tr::lng_contacts_loading(tr::now),
|
||||
});
|
||||
const auto channel = id.message.channel
|
||||
? session->data().channel(id.message.channel).get()
|
||||
const auto channel = id.channel
|
||||
? session->data().channel(id.channel).get()
|
||||
: nullptr;
|
||||
const auto callback = [=](ChannelData *channel, MsgId id) {
|
||||
consumer.put_done();
|
||||
};
|
||||
session->api().requestMessageData(channel, id.message.msg, callback);
|
||||
session->api().requestMessageData(channel, id.msg, callback);
|
||||
return rpl::lifetime();
|
||||
});
|
||||
return std::move(
|
||||
|
@ -134,180 +120,47 @@ namespace {
|
|||
}));
|
||||
}
|
||||
|
||||
auto WithPinnedTitle(not_null<Main::Session*> session, PinnedBarId id) {
|
||||
return [=](Ui::MessageBarContent &&content) {
|
||||
const auto item = session->data().message(id.message);
|
||||
if (!item) {
|
||||
return std::move(content);
|
||||
}
|
||||
const auto media = item->media();
|
||||
const auto poll = media ? media->poll() : nullptr;
|
||||
content.title = (id.type == PinnedIdType::First)
|
||||
? tr::lng_pinned_previous(tr::now) // #TODO pinned first?
|
||||
: (id.type == PinnedIdType::Middle)
|
||||
? tr::lng_pinned_previous(tr::now)
|
||||
: !poll
|
||||
? tr::lng_pinned_message(tr::now)
|
||||
: poll->quiz()
|
||||
? tr::lng_pinned_quiz(tr::now)
|
||||
: tr::lng_pinned_poll(tr::now);
|
||||
return std::move(content);
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PinnedBar::PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedBarId> itemId,
|
||||
bool withClose)
|
||||
: _wrap(parent, object_ptr<Ui::RpWidget>(parent))
|
||||
, _close(withClose
|
||||
? std::make_unique<Ui::IconButton>(
|
||||
_wrap.entity(),
|
||||
st::historyReplyCancel)
|
||||
: nullptr)
|
||||
, _shadow(std::make_unique<Ui::PlainShadow>(_wrap.parentWidget())) {
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
rpl::producer<Ui::MessageBarContent> MessageBarContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id) {
|
||||
return ContentByItemId(session, id);
|
||||
}
|
||||
|
||||
_wrap.entity()->paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
QPainter(_wrap.entity()).fillRect(clip, st::historyPinnedBg);
|
||||
}, lifetime());
|
||||
_wrap.setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
rpl::duplicate(
|
||||
itemId
|
||||
rpl::producer<Ui::MessageBarContent> PinnedBarContent(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedBarId> id) {
|
||||
return std::move(
|
||||
id
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::map([=](PinnedBarId id) {
|
||||
return ContentByItemId(session, id);
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::filter([=](const Ui::MessageBarContent &content) {
|
||||
return !content.title.isEmpty() || !content.text.text.isEmpty();
|
||||
}) | rpl::start_with_next([=](Ui::MessageBarContent &&content) {
|
||||
const auto creating = !_bar;
|
||||
if (creating) {
|
||||
createControls();
|
||||
}
|
||||
_bar->set(std::move(content));
|
||||
if (creating) {
|
||||
_bar->finishAnimating();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
std::move(
|
||||
itemId
|
||||
) | rpl::map([=](PinnedBarId id) {
|
||||
return !id.message;
|
||||
}) | rpl::start_with_next_done([=](bool hidden) {
|
||||
_shouldBeShown = !hidden;
|
||||
if (!_forceHidden) {
|
||||
_wrap.toggle(_shouldBeShown, anim::type::normal);
|
||||
} else if (!_shouldBeShown) {
|
||||
_bar = nullptr;
|
||||
}
|
||||
}, [=] {
|
||||
_forceHidden = true;
|
||||
_wrap.toggle(false, anim::type::normal);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void PinnedBar::createControls() {
|
||||
Expects(!_bar);
|
||||
|
||||
_bar = std::make_unique<Ui::MessageBar>(
|
||||
_wrap.entity(),
|
||||
st::defaultMessageBar);
|
||||
if (_close) {
|
||||
_close->raise();
|
||||
}
|
||||
|
||||
// Clicks.
|
||||
_bar->widget()->setCursor(style::cur_pointer);
|
||||
_bar->widget()->events(
|
||||
) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return (event->type() == QEvent::MouseButtonPress);
|
||||
}) | rpl::map([=] {
|
||||
return _bar->widget()->events(
|
||||
) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return (event->type() == QEvent::MouseButtonRelease);
|
||||
}) | rpl::take(1) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return _bar->widget()->rect().contains(
|
||||
static_cast<QMouseEvent*>(event.get())->pos());
|
||||
});
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::map([] {
|
||||
return rpl::empty_value();
|
||||
}) | rpl::start_to_stream(_barClicks, _bar->widget()->lifetime());
|
||||
|
||||
_bar->widget()->move(0, 0);
|
||||
_bar->widget()->show();
|
||||
_wrap.entity()->resize(_wrap.entity()->width(), _bar->widget()->height());
|
||||
|
||||
_wrap.geometryValue(
|
||||
) | rpl::start_with_next([=](QRect rect) {
|
||||
_shadow->setGeometry(
|
||||
rect.x(),
|
||||
rect.y() + rect.height(),
|
||||
rect.width(),
|
||||
st::lineWidth);
|
||||
_bar->widget()->resizeToWidth(
|
||||
rect.width() - (_close ? _close->width() : 0));
|
||||
const auto hidden = _wrap.isHidden() || !rect.height();
|
||||
if (_shadow->isHidden() != hidden) {
|
||||
_shadow->setVisible(!hidden);
|
||||
}
|
||||
if (_close) {
|
||||
_close->moveToRight(0, 0);
|
||||
}
|
||||
}, _bar->widget()->lifetime());
|
||||
|
||||
_wrap.shownValue(
|
||||
) | rpl::skip(
|
||||
1
|
||||
) | rpl::filter([=](bool shown) {
|
||||
return !shown && !_forceHidden;
|
||||
}) | rpl::start_with_next([=] {
|
||||
_bar = nullptr;
|
||||
}, _bar->widget()->lifetime());
|
||||
|
||||
Ensures(_bar != nullptr);
|
||||
}
|
||||
|
||||
void PinnedBar::show() {
|
||||
if (!_forceHidden) {
|
||||
return;
|
||||
}
|
||||
_forceHidden = false;
|
||||
if (_shouldBeShown) {
|
||||
_wrap.show(anim::type::instant);
|
||||
_shadow->show();
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedBar::hide() {
|
||||
if (_forceHidden) {
|
||||
return;
|
||||
}
|
||||
_forceHidden = true;
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
}
|
||||
|
||||
void PinnedBar::raise() {
|
||||
_wrap.raise();
|
||||
_shadow->raise();
|
||||
}
|
||||
|
||||
void PinnedBar::move(int x, int y) {
|
||||
_wrap.move(x, y);
|
||||
}
|
||||
|
||||
void PinnedBar::resizeToWidth(int width) {
|
||||
_wrap.entity()->resizeToWidth(width);
|
||||
}
|
||||
|
||||
int PinnedBar::height() const {
|
||||
return !_forceHidden
|
||||
? _wrap.height()
|
||||
: _shouldBeShown
|
||||
? st::historyReplyHeight
|
||||
: 0;
|
||||
}
|
||||
|
||||
rpl::producer<int> PinnedBar::heightValue() const {
|
||||
return _wrap.heightValue();
|
||||
}
|
||||
|
||||
rpl::producer<> PinnedBar::closeClicks() const {
|
||||
return !_close
|
||||
? (rpl::never<>() | rpl::type_erased())
|
||||
: (_close->clicks() | rpl::map([] { return rpl::empty_value(); }));
|
||||
}
|
||||
|
||||
rpl::producer<> PinnedBar::barClicks() const {
|
||||
return _barClicks.events();
|
||||
return ContentByItemId(
|
||||
session,
|
||||
id.message
|
||||
) | rpl::map(WithPinnedTitle(session, id));
|
||||
}) | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -7,9 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/chat/message_bar.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
@ -17,10 +18,15 @@ class Session;
|
|||
namespace Ui {
|
||||
class IconButton;
|
||||
class PlainShadow;
|
||||
struct MessageBarContent;
|
||||
} // namespace Ui
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> MessageBarContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id);
|
||||
|
||||
enum class PinnedIdType;
|
||||
struct PinnedBarId {
|
||||
FullMsgId message;
|
||||
|
@ -33,42 +39,8 @@ struct PinnedBarId {
|
|||
return std::tie(message, type) == std::tie(other.message, other.type);
|
||||
}
|
||||
};
|
||||
|
||||
class PinnedBar final {
|
||||
public:
|
||||
PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedBarId> itemId,
|
||||
bool withClose = false);
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void raise();
|
||||
|
||||
void move(int x, int y);
|
||||
void resizeToWidth(int width);
|
||||
[[nodiscard]] int height() const;
|
||||
[[nodiscard]] rpl::producer<int> heightValue() const;
|
||||
[[nodiscard]] rpl::producer<> closeClicks() const;
|
||||
[[nodiscard]] rpl::producer<> barClicks() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _wrap.lifetime();
|
||||
}
|
||||
|
||||
private:
|
||||
void createControls();
|
||||
|
||||
Ui::SlideWrap<> _wrap;
|
||||
std::unique_ptr<Ui::MessageBar> _bar;
|
||||
std::unique_ptr<Ui::IconButton> _close;
|
||||
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
rpl::event_stream<Ui::MessageBarContent> _content;
|
||||
rpl::event_stream<> _barClicks;
|
||||
bool _shouldBeShown = false;
|
||||
bool _forceHidden = false;
|
||||
|
||||
};
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> PinnedBarContent(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedBarId> id);
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/effects/animations.h"
|
||||
|
||||
class Painter;
|
||||
|
||||
|
|
195
Telegram/SourceFiles/ui/chat/pinned_bar.cpp
Normal file
195
Telegram/SourceFiles/ui/chat/pinned_bar.cpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
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/pinned_bar.h"
|
||||
|
||||
#include "ui/chat/message_bar.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/palette.h"
|
||||
|
||||
#include <QtGui/QtEvents>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
PinnedBar::PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<MessageBarContent> content,
|
||||
bool withClose)
|
||||
: _wrap(parent, object_ptr<RpWidget>(parent))
|
||||
, _close(withClose
|
||||
? std::make_unique<IconButton>(
|
||||
_wrap.entity(),
|
||||
st::historyReplyCancel)
|
||||
: nullptr)
|
||||
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget())) {
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
|
||||
_wrap.entity()->paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
QPainter(_wrap.entity()).fillRect(clip, st::historyPinnedBg);
|
||||
}, lifetime());
|
||||
_wrap.setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
auto copy = std::move(
|
||||
content
|
||||
) | rpl::start_spawning(_wrap.lifetime());
|
||||
|
||||
rpl::duplicate(
|
||||
copy
|
||||
) | rpl::filter([=](const MessageBarContent &content) {
|
||||
return !content.title.isEmpty() || !content.text.text.isEmpty();
|
||||
}) | rpl::start_with_next([=](MessageBarContent &&content) {
|
||||
const auto creating = !_bar;
|
||||
if (creating) {
|
||||
createControls();
|
||||
}
|
||||
_bar->set(std::move(content));
|
||||
if (creating) {
|
||||
_bar->finishAnimating();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
std::move(
|
||||
copy
|
||||
) | rpl::map([=](const MessageBarContent &content) {
|
||||
return content.title.isEmpty() || content.text.text.isEmpty();
|
||||
}) | rpl::start_with_next_done([=](bool hidden) {
|
||||
_shouldBeShown = !hidden;
|
||||
if (!_forceHidden) {
|
||||
_wrap.toggle(_shouldBeShown, anim::type::normal);
|
||||
} else if (!_shouldBeShown) {
|
||||
_bar = nullptr;
|
||||
}
|
||||
}, [=] {
|
||||
_forceHidden = true;
|
||||
_wrap.toggle(false, anim::type::normal);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
PinnedBar::~PinnedBar() = default;
|
||||
|
||||
void PinnedBar::createControls() {
|
||||
Expects(!_bar);
|
||||
|
||||
_bar = std::make_unique<MessageBar>(
|
||||
_wrap.entity(),
|
||||
st::defaultMessageBar);
|
||||
if (_close) {
|
||||
_close->raise();
|
||||
}
|
||||
|
||||
// Clicks.
|
||||
_bar->widget()->setCursor(style::cur_pointer);
|
||||
_bar->widget()->events(
|
||||
) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return (event->type() == QEvent::MouseButtonPress);
|
||||
}) | rpl::map([=] {
|
||||
return _bar->widget()->events(
|
||||
) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return (event->type() == QEvent::MouseButtonRelease);
|
||||
}) | rpl::take(1) | rpl::filter([=](not_null<QEvent*> event) {
|
||||
return _bar->widget()->rect().contains(
|
||||
static_cast<QMouseEvent*>(event.get())->pos());
|
||||
});
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::map([] {
|
||||
return rpl::empty_value();
|
||||
}) | rpl::start_to_stream(_barClicks, _bar->widget()->lifetime());
|
||||
|
||||
_bar->widget()->move(0, 0);
|
||||
_bar->widget()->show();
|
||||
_wrap.entity()->resize(_wrap.entity()->width(), _bar->widget()->height());
|
||||
|
||||
_wrap.geometryValue(
|
||||
) | rpl::start_with_next([=](QRect rect) {
|
||||
_shadow->setGeometry(
|
||||
rect.x(),
|
||||
rect.y() + rect.height(),
|
||||
rect.width(),
|
||||
st::lineWidth);
|
||||
_bar->widget()->resizeToWidth(
|
||||
rect.width() - (_close ? _close->width() : 0));
|
||||
const auto hidden = _wrap.isHidden() || !rect.height();
|
||||
if (_shadow->isHidden() != hidden) {
|
||||
_shadow->setVisible(!hidden);
|
||||
}
|
||||
if (_close) {
|
||||
_close->moveToRight(0, 0);
|
||||
}
|
||||
}, _bar->widget()->lifetime());
|
||||
|
||||
_wrap.shownValue(
|
||||
) | rpl::skip(
|
||||
1
|
||||
) | rpl::filter([=](bool shown) {
|
||||
return !shown && !_forceHidden;
|
||||
}) | rpl::start_with_next([=] {
|
||||
_bar = nullptr;
|
||||
}, _bar->widget()->lifetime());
|
||||
|
||||
Ensures(_bar != nullptr);
|
||||
}
|
||||
|
||||
void PinnedBar::show() {
|
||||
if (!_forceHidden) {
|
||||
return;
|
||||
}
|
||||
_forceHidden = false;
|
||||
if (_shouldBeShown) {
|
||||
_wrap.show(anim::type::instant);
|
||||
_shadow->show();
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedBar::hide() {
|
||||
if (_forceHidden) {
|
||||
return;
|
||||
}
|
||||
_forceHidden = true;
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
}
|
||||
|
||||
void PinnedBar::raise() {
|
||||
_wrap.raise();
|
||||
_shadow->raise();
|
||||
}
|
||||
|
||||
void PinnedBar::move(int x, int y) {
|
||||
_wrap.move(x, y);
|
||||
}
|
||||
|
||||
void PinnedBar::resizeToWidth(int width) {
|
||||
_wrap.entity()->resizeToWidth(width);
|
||||
}
|
||||
|
||||
int PinnedBar::height() const {
|
||||
return !_forceHidden
|
||||
? _wrap.height()
|
||||
: _shouldBeShown
|
||||
? st::historyReplyHeight
|
||||
: 0;
|
||||
}
|
||||
|
||||
rpl::producer<int> PinnedBar::heightValue() const {
|
||||
return _wrap.heightValue();
|
||||
}
|
||||
|
||||
rpl::producer<> PinnedBar::closeClicks() const {
|
||||
return !_close
|
||||
? (rpl::never<>() | rpl::type_erased())
|
||||
: (_close->clicks() | rpl::map([] { return rpl::empty_value(); }));
|
||||
}
|
||||
|
||||
rpl::producer<> PinnedBar::barClicks() const {
|
||||
return _barClicks.events();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
54
Telegram/SourceFiles/ui/chat/pinned_bar.h
Normal file
54
Telegram/SourceFiles/ui/chat/pinned_bar.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
struct MessageBarContent;
|
||||
class MessageBar;
|
||||
class IconButton;
|
||||
class PlainShadow;
|
||||
|
||||
class PinnedBar final {
|
||||
public:
|
||||
PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<Ui::MessageBarContent> content,
|
||||
bool withClose = false);
|
||||
~PinnedBar();
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void raise();
|
||||
|
||||
void move(int x, int y);
|
||||
void resizeToWidth(int width);
|
||||
[[nodiscard]] int height() const;
|
||||
[[nodiscard]] rpl::producer<int> heightValue() const;
|
||||
[[nodiscard]] rpl::producer<> closeClicks() const;
|
||||
[[nodiscard]] rpl::producer<> barClicks() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _wrap.lifetime();
|
||||
}
|
||||
|
||||
private:
|
||||
void createControls();
|
||||
|
||||
Ui::SlideWrap<> _wrap;
|
||||
std::unique_ptr<Ui::MessageBar> _bar;
|
||||
std::unique_ptr<Ui::IconButton> _close;
|
||||
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
rpl::event_stream<> _barClicks;
|
||||
bool _shouldBeShown = false;
|
||||
bool _forceHidden = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -34,6 +34,8 @@ PRIVATE
|
|||
ui/ui_pch.h
|
||||
ui/chat/message_bar.cpp
|
||||
ui/chat/message_bar.h
|
||||
ui/chat/pinned_bar.cpp
|
||||
ui/chat/pinned_bar.h
|
||||
ui/text/format_values.cpp
|
||||
ui/text/format_values.h
|
||||
ui/text/text_options.cpp
|
||||
|
|
Loading…
Reference in a new issue