mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-30 23:38:25 +00:00
Move third column from HistoryWidget to MainWidget.
This commit is contained in:
parent
f162462111
commit
5e7aa4ff81
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "base/timer.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
@ -132,6 +133,13 @@ public:
|
||||
not_null<UserData*> user,
|
||||
PhotoId afterId);
|
||||
|
||||
void stickerSetInstalled(uint64 setId) {
|
||||
_stickerSetInstalled.fire_copy(setId);
|
||||
}
|
||||
rpl::producer<uint64> stickerSetInstalled() const {
|
||||
return _stickerSetInstalled.events();
|
||||
}
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
private:
|
||||
@ -262,4 +270,6 @@ private:
|
||||
|
||||
base::Observable<PeerData*> _fullPeerUpdated;
|
||||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
};
|
||||
|
@ -71,6 +71,7 @@ QByteArray AuthSessionData::serialize() const {
|
||||
for (auto peerId : _variables.groupStickersSectionHidden) {
|
||||
stream << quint64(peerId);
|
||||
}
|
||||
stream << qint32(_variables.thirdSectionInfoEnabled ? 1 : 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -89,7 +90,8 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
qint32 floatPlayerColumn = static_cast<qint32>(Window::Column::Second);
|
||||
qint32 floatPlayerCorner = static_cast<qint32>(RectPart::TopRight);
|
||||
QMap<QString, QString> soundOverrides;
|
||||
OrderedSet<PeerId> groupStickersSectionHidden;
|
||||
base::flat_set<PeerId> groupStickersSectionHidden;
|
||||
qint32 thirdSectionInfoEnabled = 0;
|
||||
stream >> selectorTab;
|
||||
stream >> lastSeenWarningSeen;
|
||||
if (!stream.atEnd()) {
|
||||
@ -123,6 +125,9 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> thirdSectionInfoEnabled;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
|
||||
return;
|
||||
@ -152,6 +157,24 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
case RectPart::BottomRight: _variables.floatPlayerCorner = uncheckedCorner; break;
|
||||
}
|
||||
_variables.groupStickersSectionHidden = std::move(groupStickersSectionHidden);
|
||||
_variables.thirdSectionInfoEnabled = thirdSectionInfoEnabled;
|
||||
}
|
||||
|
||||
void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||
if (enabled) {
|
||||
setThirdSectionInfoEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
|
||||
if (_variables.thirdSectionInfoEnabled != enabled) {
|
||||
_variables.thirdSectionInfoEnabled = enabled;
|
||||
if (enabled) {
|
||||
setTabbedSelectorSectionEnabled(false);
|
||||
}
|
||||
_thirdSectionInfoEnabledValue.fire_copy(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
QString AuthSessionData::getSoundPath(const QString &key) const {
|
||||
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Storage {
|
||||
@ -100,8 +101,14 @@ public:
|
||||
bool tabbedSelectorSectionEnabled() const {
|
||||
return _variables.tabbedSelectorSectionEnabled;
|
||||
}
|
||||
void setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||
void setTabbedSelectorSectionEnabled(bool enabled);
|
||||
bool thirdSectionInfoEnabled() const {
|
||||
return _variables.thirdSectionInfoEnabled;
|
||||
}
|
||||
void setThirdSectionInfoEnabled(bool enabled);
|
||||
rpl::producer<bool> thirdSectionInfoEnabledValue() const {
|
||||
return _thirdSectionInfoEnabledValue.events_starting_with(
|
||||
thirdSectionInfoEnabled());
|
||||
}
|
||||
void setLastTimeVideoPlayedAt(TimeMs time) {
|
||||
_lastTimeVideoPlayedAt = time;
|
||||
@ -155,7 +162,8 @@ private:
|
||||
QMap<QString, QString> soundOverrides;
|
||||
Window::Column floatPlayerColumn;
|
||||
RectPart floatPlayerCorner;
|
||||
OrderedSet<PeerId> groupStickersSectionHidden;
|
||||
base::flat_set<PeerId> groupStickersSectionHidden;
|
||||
bool thirdSectionInfoEnabled = false;
|
||||
};
|
||||
|
||||
base::Variable<bool> _contactsLoaded = { false };
|
||||
@ -167,6 +175,8 @@ private:
|
||||
base::Observable<not_null<const HistoryItem*>> _repaintLogEntry;
|
||||
base::Observable<void> _pendingHistoryResize;
|
||||
base::Observable<ItemVisibilityQuery> _queryItemVisibility;
|
||||
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
|
||||
|
||||
Variables _variables;
|
||||
TimeMs _lastTimeVideoPlayedAt = 0;
|
||||
|
||||
|
@ -56,12 +56,12 @@ void StickerSetBox::prepare() {
|
||||
onUpdateButtons();
|
||||
|
||||
connect(_inner, SIGNAL(updateButtons()), this, SLOT(onUpdateButtons()));
|
||||
connect(_inner, SIGNAL(installed(uint64)), this, SLOT(onInstalled(uint64)));
|
||||
}
|
||||
|
||||
void StickerSetBox::onInstalled(uint64 setId) {
|
||||
emit installed(setId);
|
||||
closeBox();
|
||||
_inner->setInstalled()
|
||||
| rpl::on_next([this](auto &&setId) {
|
||||
Auth().api().stickerSetInstalled(setId);
|
||||
closeBox();
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void StickerSetBox::onAddStickers() {
|
||||
@ -250,7 +250,7 @@ void StickerSetBox::Inner::installDone(const MTPmessages_StickerSetInstallResult
|
||||
Local::writeInstalledStickers();
|
||||
Auth().data().stickersUpdated().notify(true);
|
||||
}
|
||||
emit installed(_setId);
|
||||
_setInstalled.fire_copy(_setId);
|
||||
}
|
||||
|
||||
bool StickerSetBox::Inner::installFail(const RPCError &error) {
|
||||
|
@ -35,9 +35,6 @@ class StickerSetBox : public BoxContent, public RPCSender {
|
||||
public:
|
||||
StickerSetBox(QWidget*, const MTPInputStickerSet &set);
|
||||
|
||||
signals:
|
||||
void installed(uint64 id);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
|
||||
@ -48,8 +45,6 @@ private slots:
|
||||
void onShareStickers();
|
||||
void onUpdateButtons();
|
||||
|
||||
void onInstalled(uint64 id);
|
||||
|
||||
private:
|
||||
void updateButtons();
|
||||
|
||||
@ -74,6 +69,9 @@ public:
|
||||
QString shortName() const;
|
||||
|
||||
void install();
|
||||
rpl::producer<uint64> setInstalled() const {
|
||||
return _setInstalled.events();
|
||||
}
|
||||
|
||||
~Inner();
|
||||
|
||||
@ -89,7 +87,6 @@ private slots:
|
||||
|
||||
signals:
|
||||
void updateButtons();
|
||||
void installed(uint64 id);
|
||||
|
||||
private:
|
||||
void updateSelected();
|
||||
@ -127,4 +124,6 @@ private:
|
||||
QTimer _previewTimer;
|
||||
int _previewShown = -1;
|
||||
|
||||
rpl::event_stream<uint64> _setInstalled;
|
||||
|
||||
};
|
||||
|
@ -1094,7 +1094,7 @@ void StickersBox::Inner::saveGroupSet() {
|
||||
auto newId = (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0;
|
||||
if (newId != oldId) {
|
||||
Auth().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput);
|
||||
App::main()->onStickersInstalled(Stickers::MegagroupSetId);
|
||||
Auth().api().stickerSetInstalled(Stickers::MegagroupSetId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
||||
|
||||
EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
||||
, _picker(this) {
|
||||
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
|
||||
updateSize();
|
||||
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
@ -381,7 +381,7 @@ EmojiListWidget::SectionInfo EmojiListWidget::sectionInfoByOffset(int yOffset) c
|
||||
return result;
|
||||
}
|
||||
|
||||
int EmojiListWidget::countHeight() {
|
||||
int EmojiListWidget::countDesiredHeight() {
|
||||
return sectionInfo(kEmojiSectionCount - 1).rowsBottom + st::emojiPanPadding;
|
||||
}
|
||||
|
||||
@ -648,11 +648,7 @@ void EmojiListWidget::refreshRecent() {
|
||||
clearSelection();
|
||||
_emoji[0] = Ui::Emoji::GetSection(Section::Recent);
|
||||
_counts[0] = _emoji[0].size();
|
||||
auto h = countHeight();
|
||||
if (h != height()) {
|
||||
resize(width(), h);
|
||||
update();
|
||||
}
|
||||
updateSize();
|
||||
}
|
||||
|
||||
bool EmojiListWidget::event(QEvent *e) {
|
||||
|
@ -126,7 +126,7 @@ protected:
|
||||
|
||||
TabbedSelector::InnerFooter *getFooter() const override;
|
||||
void processHideFinished() override;
|
||||
int countHeight() override;
|
||||
int countDesiredHeight() override;
|
||||
|
||||
private:
|
||||
class Footer;
|
||||
|
@ -122,7 +122,7 @@ void GifsListWidget::Footer::processPanelHideFinished() {
|
||||
|
||||
GifsListWidget::GifsListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
||||
, _section(Section::Gifs) {
|
||||
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
|
||||
updateSize();
|
||||
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
@ -174,17 +174,12 @@ void GifsListWidget::checkLoadMore() {
|
||||
}
|
||||
}
|
||||
|
||||
int GifsListWidget::countHeight() {
|
||||
auto visibleHeight = getVisibleBottom() - getVisibleTop();
|
||||
if (visibleHeight <= 0) {
|
||||
visibleHeight = st::emojiPanMaxHeight - st::emojiCategory.height;
|
||||
}
|
||||
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
|
||||
int GifsListWidget::countDesiredHeight() {
|
||||
auto result = st::stickerPanPadding;
|
||||
for (int i = 0, l = _rows.count(); i < l; ++i) {
|
||||
result += _rows[i].height;
|
||||
}
|
||||
return qMax(minimalLastHeight, result) + st::stickerPanPadding;
|
||||
return result + st::stickerPanPadding;
|
||||
}
|
||||
|
||||
GifsListWidget::~GifsListWidget() {
|
||||
@ -475,11 +470,7 @@ void GifsListWidget::refreshSavedGifs() {
|
||||
}
|
||||
deleteUnusedGifLayouts();
|
||||
|
||||
auto newHeight = countHeight();
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
}
|
||||
|
||||
updateSize();
|
||||
update();
|
||||
}
|
||||
|
||||
@ -642,8 +633,7 @@ int GifsListWidget::refreshInlineRows(const InlineCacheEntry *entry, bool result
|
||||
inlineRowFinalize(row, sumWidth, true);
|
||||
}
|
||||
|
||||
int32 h = countHeight();
|
||||
if (h != height()) resize(width(), h);
|
||||
updateSize();
|
||||
update();
|
||||
|
||||
_lastMousePos = QCursor::pos();
|
||||
|
@ -82,7 +82,7 @@ protected:
|
||||
TabbedSelector::InnerFooter *getFooter() const override;
|
||||
void processHideFinished() override;
|
||||
void processPanelHideFinished() override;
|
||||
int countHeight() override;
|
||||
int countDesiredHeight() override;
|
||||
|
||||
private slots:
|
||||
void onPreview();
|
||||
|
@ -262,7 +262,7 @@ void SetIsFaved(not_null<DocumentData*> document, base::optional<std::vector<not
|
||||
}
|
||||
Local::writeFavedStickers();
|
||||
Auth().data().stickersUpdated().notify(true);
|
||||
App::main()->onStickersInstalled(FavedSetId);
|
||||
Auth().api().stickerSetInstalled(FavedSetId);
|
||||
}
|
||||
|
||||
void RequestSetToPushFaved(not_null<DocumentData*> document) {
|
||||
|
@ -440,7 +440,7 @@ StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Control
|
||||
, _addText(lang(lng_stickers_featured_add).toUpper())
|
||||
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
||||
, _settings(this, lang(lng_stickers_you_have)) {
|
||||
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
|
||||
updateSize();
|
||||
|
||||
setMouseTracking(true);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
@ -559,11 +559,8 @@ StickersListWidget::SectionInfo StickersListWidget::sectionInfoByOffset(int yOff
|
||||
return result;
|
||||
}
|
||||
|
||||
int StickersListWidget::countHeight() {
|
||||
auto visibleHeight = getVisibleBottom() - getVisibleTop();
|
||||
if (visibleHeight <= 0) {
|
||||
visibleHeight = st::emojiPanMaxHeight - st::emojiCategory.height;
|
||||
}
|
||||
int StickersListWidget::countDesiredHeight() {
|
||||
auto visibleHeight = minimalHeight();
|
||||
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
|
||||
auto countResult = [this, minimalLastHeight] {
|
||||
if (_section == Section::Featured) {
|
||||
@ -1154,10 +1151,7 @@ void StickersListWidget::refreshStickers() {
|
||||
appendSet(_featuredSets, setId, AppendSkip::Installed);
|
||||
}
|
||||
|
||||
auto newHeight = countHeight();
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
}
|
||||
updateSize();
|
||||
|
||||
if (_footer) {
|
||||
_footer->refreshIcons(ValidateIconAnimations::None);
|
||||
@ -1283,12 +1277,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
||||
}
|
||||
|
||||
if (performResize && (_section == Section::Stickers || _section == Section::Featured)) {
|
||||
int32 h = countHeight();
|
||||
if (h != height()) {
|
||||
resize(width(), h);
|
||||
update();
|
||||
}
|
||||
|
||||
updateSize();
|
||||
updateSelected();
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ protected:
|
||||
TabbedSelector::InnerFooter *getFooter() const override;
|
||||
void processHideFinished() override;
|
||||
void processPanelHideFinished() override;
|
||||
int countHeight() override;
|
||||
int countDesiredHeight() override;
|
||||
|
||||
private slots:
|
||||
void onSettings();
|
||||
|
@ -34,10 +34,20 @@ constexpr auto kDelayedHideTimeoutMs = 3000;
|
||||
|
||||
} // namespace
|
||||
|
||||
TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controller) : TabbedPanel(parent, controller, object_ptr<TabbedSelector>(nullptr, controller)) {
|
||||
TabbedPanel::TabbedPanel(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller)
|
||||
: TabbedPanel(
|
||||
parent,
|
||||
controller,
|
||||
object_ptr<TabbedSelector>(nullptr, controller)) {
|
||||
}
|
||||
|
||||
TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : TWidget(parent)
|
||||
TabbedPanel::TabbedPanel(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
object_ptr<TabbedSelector> selector)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _selector(std::move(selector)) {
|
||||
_selector->setParent(this);
|
||||
@ -52,6 +62,9 @@ TabbedPanel::TabbedPanel(QWidget *parent, not_null<Window::Controller*> controll
|
||||
_controller->disableGifPauseReason(Window::GifPauseReason::SavedGifs);
|
||||
}
|
||||
});
|
||||
_selector->showRequests()
|
||||
| rpl::on_next([this](auto&&) { showFromSelector(); })
|
||||
| rpl::start(lifetime());
|
||||
|
||||
resize(QRect(0, 0, st::emojiPanWidth, st::emojiPanMaxHeight).marginsAdded(innerPadding()).size());
|
||||
|
||||
@ -376,11 +389,7 @@ bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabbedPanel::stickersInstalled(uint64 setId) {
|
||||
if (isDestroying()) {
|
||||
return;
|
||||
}
|
||||
_selector->stickersInstalled(setId);
|
||||
void TabbedPanel::showFromSelector() {
|
||||
if (isHidden()) {
|
||||
moveByBottom();
|
||||
startShowAnimation();
|
||||
|
@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/twidget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Window {
|
||||
@ -35,7 +35,7 @@ namespace ChatHelpers {
|
||||
|
||||
class TabbedSelector;
|
||||
|
||||
class TabbedPanel : public TWidget {
|
||||
class TabbedPanel : public Ui::RpWidget{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -51,8 +51,6 @@ public:
|
||||
return _hiding || _hideTimer.isActive();
|
||||
}
|
||||
|
||||
void stickersInstalled(uint64 setId);
|
||||
|
||||
bool overlaps(const QRect &globalRect) const;
|
||||
|
||||
void showAnimated();
|
||||
@ -79,6 +77,7 @@ private:
|
||||
bool isDestroying() const {
|
||||
return !_selector;
|
||||
}
|
||||
void showFromSelector();
|
||||
|
||||
style::margins innerPadding() const;
|
||||
|
||||
|
@ -25,11 +25,49 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
||||
TabbedSection::TabbedSection(QWidget *parent, not_null<Window::Controller*> controller) : TabbedSection(parent, controller, object_ptr<TabbedSelector>(this, controller)) {
|
||||
TabbedMemento::TabbedMemento(
|
||||
object_ptr<TabbedSelector> selector,
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod)
|
||||
: _selector(std::move(selector))
|
||||
, _returnMethod(std::move(returnMethod)) {
|
||||
}
|
||||
|
||||
TabbedSection::TabbedSection(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector) : Window::AbstractSectionWidget(parent, controller)
|
||||
, _selector(std::move(selector)) {
|
||||
object_ptr<Window::SectionWidget> TabbedMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
return object_ptr<TabbedSection>(
|
||||
parent,
|
||||
controller,
|
||||
std::move(_selector),
|
||||
std::move(_returnMethod));
|
||||
}
|
||||
|
||||
TabbedMemento::~TabbedMemento() {
|
||||
if (_returnMethod && _selector) {
|
||||
_returnMethod(std::move(_selector));
|
||||
}
|
||||
}
|
||||
|
||||
TabbedSection::TabbedSection(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller)
|
||||
: TabbedSection(
|
||||
parent,
|
||||
controller,
|
||||
object_ptr<TabbedSelector>(this, controller),
|
||||
base::lambda<void(object_ptr<TabbedSelector>)>()) {
|
||||
}
|
||||
|
||||
TabbedSection::TabbedSection(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
object_ptr<TabbedSelector> selector,
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod)
|
||||
: Window::SectionWidget(parent, controller)
|
||||
, _selector(std::move(selector))
|
||||
, _returnMethod(std::move(returnMethod)) {
|
||||
resize(st::emojiPanWidth, st::emojiPanMaxHeight);
|
||||
|
||||
_selector->setParent(this);
|
||||
@ -68,17 +106,24 @@ object_ptr<TabbedSelector> TabbedSection::takeSelector() {
|
||||
QPointer<TabbedSelector> TabbedSection::getSelector() const {
|
||||
return _selector.data();
|
||||
}
|
||||
|
||||
void TabbedSection::stickersInstalled(uint64 setId) {
|
||||
_selector->stickersInstalled(setId);
|
||||
bool TabbedSection::showInternal(
|
||||
not_null<Window::SectionMemento*> memento) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TabbedSection::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool TabbedSection::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _selector->wheelEventFromFloatPlayer(e);
|
||||
}
|
||||
|
||||
QRect TabbedSection::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect TabbedSection::rectForFloatPlayer() const {
|
||||
return _selector->rectForFloatPlayer();
|
||||
}
|
||||
|
||||
TabbedSection::~TabbedSection() {
|
||||
beforeHiding();
|
||||
if (_returnMethod) {
|
||||
_returnMethod(takeSelector());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ChatHelpers
|
||||
|
@ -21,15 +21,42 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#pragma once
|
||||
|
||||
#include "window/section_widget.h"
|
||||
#include "window/section_memento.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
||||
class TabbedSelector;
|
||||
|
||||
class TabbedSection : public Window::AbstractSectionWidget {
|
||||
class TabbedMemento : public Window::SectionMemento {
|
||||
public:
|
||||
TabbedSection(QWidget *parent, not_null<Window::Controller*> controller);
|
||||
TabbedSection(QWidget *parent, not_null<Window::Controller*> controller, object_ptr<TabbedSelector> selector);
|
||||
TabbedMemento(
|
||||
object_ptr<TabbedSelector> selector,
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod);
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
~TabbedMemento();
|
||||
|
||||
private:
|
||||
object_ptr<TabbedSelector> _selector;
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> _returnMethod;
|
||||
|
||||
};
|
||||
|
||||
class TabbedSection : public Window::SectionWidget {
|
||||
public:
|
||||
TabbedSection(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller);
|
||||
TabbedSection(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
object_ptr<TabbedSelector> selector,
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> returnMethod);
|
||||
|
||||
void beforeHiding();
|
||||
void afterShown();
|
||||
@ -40,18 +67,28 @@ public:
|
||||
object_ptr<TabbedSelector> takeSelector();
|
||||
QPointer<TabbedSelector> getSelector() const;
|
||||
|
||||
void stickersInstalled(uint64 setId);
|
||||
|
||||
bool showInternal(
|
||||
not_null<Window::SectionMemento*> memento) override;
|
||||
bool forceAnimateBack() const override {
|
||||
return true;
|
||||
}
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
~TabbedSection();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
void showFinishedHook() override {
|
||||
afterShown();
|
||||
}
|
||||
|
||||
private:
|
||||
object_ptr<TabbedSelector> _selector;
|
||||
base::lambda<void()> _cancelledCallback;
|
||||
base::lambda<void(object_ptr<TabbedSelector>)> _returnMethod;
|
||||
|
||||
};
|
||||
|
||||
|
@ -346,6 +346,14 @@ TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> co
|
||||
}
|
||||
}));
|
||||
|
||||
Auth().api().stickerSetInstalled()
|
||||
| rpl::on_next([this](uint64 setId) {
|
||||
_tabsSlider->setActiveSection(static_cast<int>(SelectorTab::Stickers));
|
||||
stickers()->showStickerSet(setId);
|
||||
_showRequests.fire({});
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
|
||||
// setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
showAll();
|
||||
@ -356,9 +364,11 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
||||
if (e->oldSize().height() > height()) {
|
||||
_scroll->resize(_scroll->width(), contentHeight);
|
||||
auto scrollTop = _scroll->scrollTop();
|
||||
currentTab()->widget()->setMinimalHeight(contentHeight);
|
||||
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
|
||||
} else {
|
||||
auto scrollTop = _scroll->scrollTop();
|
||||
currentTab()->widget()->setMinimalHeight(contentHeight);
|
||||
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
|
||||
_scroll->resize(_scroll->width(), contentHeight);
|
||||
}
|
||||
@ -514,11 +524,6 @@ void TabbedSelector::afterShown() {
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedSelector::stickersInstalled(uint64 setId) {
|
||||
_tabsSlider->setActiveSection(static_cast<int>(SelectorTab::Stickers));
|
||||
stickers()->showStickerSet(setId);
|
||||
}
|
||||
|
||||
void TabbedSelector::showMegagroupSet(ChannelData *megagroup) {
|
||||
stickers()->showMegagroupSet(megagroup);
|
||||
}
|
||||
@ -702,15 +707,36 @@ TabbedSelector::Inner::Inner(QWidget *parent, not_null<Window::Controller*> cont
|
||||
}
|
||||
|
||||
void TabbedSelector::Inner::visibleTopBottomUpdated(int visibleTop, int visibleBottom) {
|
||||
auto oldVisibleHeight = getVisibleBottom() - getVisibleTop();
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
auto visibleHeight = getVisibleBottom() - getVisibleTop();
|
||||
if (visibleHeight != oldVisibleHeight) {
|
||||
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
|
||||
}
|
||||
|
||||
void TabbedSelector::Inner::setMinimalHeight(int newMinimalHeight) {
|
||||
if (_minimalHeight != newMinimalHeight) {
|
||||
_minimalHeight = newMinimalHeight;
|
||||
updateSize();
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedSelector::Inner::updateSize() {
|
||||
auto width = st::emojiPanWidth
|
||||
- st::emojiScroll.width
|
||||
- st::buttonRadius;
|
||||
auto height = qMax(countDesiredHeight(), minimalHeight());
|
||||
auto newSize = QSize(width, height);
|
||||
if (size() != newSize) {
|
||||
resize(newSize);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int TabbedSelector::Inner::minimalHeight() const {
|
||||
auto result = _minimalHeight;
|
||||
return (_minimalHeight > 0)
|
||||
? _minimalHeight
|
||||
: (st::emojiPanMaxHeight - st::emojiCategory.height);
|
||||
}
|
||||
|
||||
void TabbedSelector::Inner::hideFinished() {
|
||||
processHideFinished();
|
||||
if (auto footer = getFooter()) {
|
||||
|
@ -60,7 +60,6 @@ public:
|
||||
|
||||
void setRoundRadius(int radius);
|
||||
void refreshStickers();
|
||||
void stickersInstalled(uint64 setId);
|
||||
void showMegagroupSet(ChannelData *megagroup);
|
||||
void setCurrentPeer(PeerData *peer);
|
||||
|
||||
@ -88,6 +87,10 @@ public:
|
||||
bool wheelEventFromFloatPlayer(QEvent *e);
|
||||
QRect rectForFloatPlayer() const;
|
||||
|
||||
rpl::producer<> showRequests() const {
|
||||
return _showRequests.events();
|
||||
}
|
||||
|
||||
~TabbedSelector();
|
||||
|
||||
class Inner;
|
||||
@ -199,6 +202,8 @@ private:
|
||||
base::lambda<void(SelectorTab)> _afterShownCallback;
|
||||
base::lambda<void(SelectorTab)> _beforeHidingCallback;
|
||||
|
||||
rpl::event_stream<> _showRequests;
|
||||
|
||||
};
|
||||
|
||||
class TabbedSelector::Inner : public TWidget {
|
||||
@ -213,6 +218,7 @@ public:
|
||||
int getVisibleBottom() const {
|
||||
return _visibleBottom;
|
||||
}
|
||||
void setMinimalHeight(int newMinimalHeight);
|
||||
|
||||
virtual void refreshRecent() = 0;
|
||||
virtual void preloadImages() {
|
||||
@ -236,12 +242,14 @@ protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
void updateSize();
|
||||
int minimalHeight() const;
|
||||
|
||||
not_null<Window::Controller*> controller() const {
|
||||
return _controller;
|
||||
}
|
||||
|
||||
virtual int countHeight() = 0;
|
||||
virtual int countDesiredHeight() = 0;
|
||||
virtual InnerFooter *getFooter() const = 0;
|
||||
virtual void processHideFinished() {
|
||||
}
|
||||
@ -253,6 +261,7 @@ private:
|
||||
|
||||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
int _minimalHeight = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -267,11 +267,11 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
|
||||
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||
}
|
||||
|
||||
bool DialogsWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool DialogsWidget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect DialogsWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect DialogsWidget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -98,8 +98,8 @@ public:
|
||||
void onSearchMore();
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||
void notify_historyMuteUpdated(History *history);
|
||||
|
@ -262,17 +262,9 @@ void autoplayMediaInlineAsync(const FullMsgId &msgId) {
|
||||
}
|
||||
|
||||
void showPeerProfile(const PeerId &peer) {
|
||||
//if (auto main = App::main()) {
|
||||
// main->showWideSection(Profile::SectionMemento(App::peer(peer)));
|
||||
//}
|
||||
|
||||
if (auto window = App::wnd()) {
|
||||
auto memento = Info::Memento(peer);
|
||||
if (auto layer = memento.createLayer(window->controller())) {
|
||||
window->controller()->showSpecialLayer(std::move(layer));
|
||||
} else {
|
||||
App::main()->showWideSection(std::move(memento));
|
||||
}
|
||||
if (auto main = App::main()) {
|
||||
// main->showSection(Profile::SectionMemento(App::peer(peer)));
|
||||
main->showSection(Info::Memento(peer), anim::type::normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +238,7 @@ enum class WindowLayout {
|
||||
OneColumn,
|
||||
SmallColumn,
|
||||
Normal,
|
||||
ThreeColumn,
|
||||
};
|
||||
|
||||
enum class ChatLayout {
|
||||
@ -424,8 +425,13 @@ inline bool Normal() {
|
||||
return Global::AdaptiveWindowLayout() == WindowLayout::Normal;
|
||||
}
|
||||
|
||||
inline bool ThreeColumn() {
|
||||
return Global::AdaptiveWindowLayout() == WindowLayout::ThreeColumn;
|
||||
}
|
||||
|
||||
inline bool ChatNormal() {
|
||||
return !Global::AdaptiveForWide() || (Global::AdaptiveChatLayout() == ChatLayout::Normal);
|
||||
return !Global::AdaptiveForWide()
|
||||
|| (Global::AdaptiveChatLayout() == ChatLayout::Normal);
|
||||
}
|
||||
|
||||
inline bool ChatWide() {
|
||||
|
@ -22,6 +22,8 @@ using "basic.style";
|
||||
using "dialogs/dialogs.style";
|
||||
using "ui/widgets/widgets.style";
|
||||
|
||||
historyMinimalWidth: 380px;
|
||||
|
||||
historyScroll: ScrollArea(defaultScrollArea) {
|
||||
bg: historyScrollBg;
|
||||
bgOver: historyScrollBgOver;
|
||||
|
@ -88,7 +88,14 @@ private:
|
||||
|
||||
};
|
||||
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) {
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
if (column == Window::Column::Third) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = object_ptr<Widget>(parent, controller, _channel);
|
||||
result->setInternalState(geometry, this);
|
||||
return std::move(result);
|
||||
@ -427,11 +434,11 @@ void Widget::showFinishedHook() {
|
||||
_fixedBar->setAnimatingMode(false);
|
||||
}
|
||||
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect Widget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,8 @@ public:
|
||||
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
void applyFilter(FilterValue &&value);
|
||||
|
||||
@ -136,7 +136,11 @@ public:
|
||||
SectionMemento(not_null<ChannelData*> channel) : _channel(channel) {
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override;
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
not_null<ChannelData*> getChannel() const {
|
||||
return _channel;
|
||||
|
@ -47,8 +47,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "profile/profile_block_group_members.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "chat_helpers/tabbed_panel.h"
|
||||
#include "chat_helpers/tabbed_section.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "chat_helpers/tabbed_section.h"
|
||||
#include "chat_helpers/bot_keyboard.h"
|
||||
#include "chat_helpers/message_field.h"
|
||||
#include "lang/lang_keys.h"
|
||||
@ -75,101 +75,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "inline_bots/inline_results_widget.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
|
||||
// Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent.
|
||||
template <typename Object>
|
||||
class test_ptr {
|
||||
public:
|
||||
test_ptr(std::nullptr_t) {
|
||||
}
|
||||
|
||||
// No default constructor, but constructors with at least
|
||||
// one argument are simply make functions.
|
||||
template <typename Parent, typename... Args>
|
||||
explicit test_ptr(Parent &&parent, Args&&... args) : _object(new Object(std::forward<Parent>(parent), std::forward<Args>(args)...)) {
|
||||
}
|
||||
|
||||
test_ptr(const test_ptr &other) = delete;
|
||||
test_ptr &operator=(const test_ptr &other) = delete;
|
||||
test_ptr(test_ptr &&other) : _object(base::take(other._object)) {
|
||||
}
|
||||
test_ptr &operator=(test_ptr &&other) {
|
||||
auto temp = std::move(other);
|
||||
destroy();
|
||||
std::swap(_object, temp._object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
|
||||
test_ptr(test_ptr<OtherObject> &&other) : _object(base::take(other._object)) {
|
||||
}
|
||||
|
||||
template <typename OtherObject, typename = std::enable_if_t<std::is_base_of<Object, OtherObject>::value>>
|
||||
test_ptr &operator=(test_ptr<OtherObject> &&other) {
|
||||
_object = base::take(other._object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
test_ptr &operator=(std::nullptr_t) {
|
||||
_object = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// So we can pass this pointer to methods like connect().
|
||||
Object *data() const {
|
||||
return static_cast<Object*>(_object);
|
||||
}
|
||||
operator Object*() const {
|
||||
return data();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return _object != nullptr;
|
||||
}
|
||||
|
||||
Object *operator->() const {
|
||||
return data();
|
||||
}
|
||||
Object &operator*() const {
|
||||
return *data();
|
||||
}
|
||||
|
||||
// Use that instead "= new Object(parent, ...)"
|
||||
template <typename Parent, typename... Args>
|
||||
void create(Parent &&parent, Args&&... args) {
|
||||
destroy();
|
||||
_object = new Object(std::forward<Parent>(parent), std::forward<Args>(args)...);
|
||||
}
|
||||
void destroy() {
|
||||
delete base::take(_object);
|
||||
}
|
||||
void destroyDelayed() {
|
||||
if (_object) {
|
||||
if (auto widget = base::up_cast<QWidget*>(data())) {
|
||||
widget->hide();
|
||||
}
|
||||
base::take(_object)->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
~test_ptr() {
|
||||
if (auto pointer = _object) {
|
||||
if (!pointer->parent()) {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename OtherObject>
|
||||
friend class test_ptr;
|
||||
|
||||
QPointer<QObject> _object;
|
||||
|
||||
};
|
||||
|
||||
class TestClass;
|
||||
test_ptr<TestClass> tmp = { nullptr };
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kSaveTabbedSelectorSectionTimeoutMs = 1000;
|
||||
@ -739,7 +644,9 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||
_botCommandStart->hide();
|
||||
|
||||
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
|
||||
_tabbedSelectorToggle->setClickedCallback([this] { toggleTabbedSelectorMode(); });
|
||||
_tabbedSelectorToggle->setClickedCallback([this] {
|
||||
toggleTabbedSelectorMode();
|
||||
});
|
||||
|
||||
connect(_botKeyboardShow, SIGNAL(clicked()), this, SLOT(onKbToggle()));
|
||||
connect(_botKeyboardHide, SIGNAL(clicked()), this, SLOT(onKbToggle()));
|
||||
@ -819,22 +726,6 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||
}
|
||||
}
|
||||
}));
|
||||
subscribe(controller->window()->widgetGrabbed(), [this] {
|
||||
// Qt bug workaround: QWidget::render() for an arbitrary widget calls
|
||||
// sendPendingMoveAndResizeEvents(true, true) for the whole window,
|
||||
// which does something like:
|
||||
//
|
||||
// setAttribute(Qt::WA_UpdatesDisabled);
|
||||
// sendEvent(QResizeEvent);
|
||||
// setAttribute(Qt::WA_UpdatesDisabled, false);
|
||||
//
|
||||
// So if we create TabbedSection widget in HistoryWidget::resizeEvent()
|
||||
// it will get an enabled Qt::WA_UpdatesDisabled from its parent and it
|
||||
// will never be rendered, because no one will ever remove that attribute.
|
||||
//
|
||||
// So we force HistoryWidget::resizeEvent() here, without WA_UpdatesDisabled.
|
||||
myEnsureResized(this);
|
||||
});
|
||||
subscribe(Auth().data().pendingHistoryResize(), [this] { handlePendingHistoryUpdate(); });
|
||||
subscribe(Auth().data().queryItemVisibility(), [this](const AuthSessionData::ItemVisibilityQuery &query) {
|
||||
if (_a_show.animating() || _history != query.item->history() || query.item->detached() || !isVisible()) {
|
||||
@ -1152,9 +1043,6 @@ void HistoryWidget::orderWidgets() {
|
||||
_reportSpamPanel->raise();
|
||||
}
|
||||
_topShadow->raise();
|
||||
if (_rightShadow) {
|
||||
_rightShadow->raise();
|
||||
}
|
||||
if (_membersDropdown) {
|
||||
_membersDropdown->raise();
|
||||
}
|
||||
@ -1383,14 +1271,6 @@ void HistoryWidget::updateRecentStickers() {
|
||||
_tabbedSelector->refreshStickers();
|
||||
}
|
||||
|
||||
void HistoryWidget::stickersInstalled(uint64 setId) {
|
||||
if (_tabbedPanel) {
|
||||
_tabbedPanel->stickersInstalled(setId);
|
||||
} else if (_tabbedSection) {
|
||||
_tabbedSection->stickersInstalled(setId);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
|
||||
for (auto i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
|
||||
if (i.value() == req) {
|
||||
@ -2108,20 +1988,10 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
updateHistoryDownVisibility();
|
||||
updateUnreadMentionsVisibility();
|
||||
if (!_history || _a_show.animating()) {
|
||||
if (_tabbedSection && !_tabbedSection->isHidden()) {
|
||||
_tabbedSection->beforeHiding();
|
||||
}
|
||||
hideChildren();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_tabbedSection) {
|
||||
if (_tabbedSection->isHidden()) {
|
||||
_tabbedSection->show();
|
||||
_tabbedSection->afterShown();
|
||||
}
|
||||
_rightShadow->show();
|
||||
}
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->cancel->show();
|
||||
_pinnedBar->shadow->show();
|
||||
@ -2287,7 +2157,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
update();
|
||||
}
|
||||
}
|
||||
checkTabbedSelectorToggleTooltip();
|
||||
//checkTabbedSelectorToggleTooltip();
|
||||
updateMouseTracking();
|
||||
}
|
||||
|
||||
@ -2807,7 +2677,16 @@ void HistoryWidget::saveEditMsg() {
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||
}
|
||||
_saveEditMsgRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(sendFlags), _history->peer->input, MTP_int(_editMsgId), MTP_string(sending.text), MTPnullMarkup, sentEntities), rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcFail(&HistoryWidget::saveEditMsgFail, _history));
|
||||
_saveEditMsgRequestId = MTP::send(
|
||||
MTPmessages_EditMessage(
|
||||
MTP_flags(sendFlags),
|
||||
_history->peer->input,
|
||||
MTP_int(_editMsgId),
|
||||
MTP_string(sending.text),
|
||||
MTPnullMarkup,
|
||||
sentEntities),
|
||||
rpcDone(&HistoryWidget::saveEditMsgDone, _history),
|
||||
rpcFail(&HistoryWidget::saveEditMsgFail, _history));
|
||||
}
|
||||
|
||||
void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req) {
|
||||
@ -3077,15 +2956,8 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
|
||||
_topShadow->setVisible(params.withTopBarShadow ? false : true);
|
||||
_cacheOver = App::main()->grabForShowAnimation(params);
|
||||
|
||||
if (_tabbedSection && !_tabbedSection->isHidden()) {
|
||||
_tabbedSection->beforeHiding();
|
||||
}
|
||||
hideChildren();
|
||||
if (params.withTopBarShadow) _topShadow->show();
|
||||
if (params.withTabbedSection && _tabbedSection) {
|
||||
_tabbedSection->show();
|
||||
_tabbedSection->afterShown();
|
||||
}
|
||||
|
||||
if (_showDirection == Window::SlideDirection::FromLeft) {
|
||||
std::swap(_cacheUnder, _cacheOver);
|
||||
@ -3507,19 +3379,11 @@ bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
|
||||
return TWidget::eventFilter(obj, e);
|
||||
}
|
||||
|
||||
bool HistoryWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
if (playerColumn == Window::Column::Third && _tabbedSection) {
|
||||
auto tabbedColumn = (myColumn == Window::Column::First) ? Window::Column::Second : Window::Column::Third;
|
||||
return _tabbedSection->wheelEventFromFloatPlayer(e, tabbedColumn, playerColumn);
|
||||
}
|
||||
bool HistoryWidget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect HistoryWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
if (playerColumn == Window::Column::Third && _tabbedSection) {
|
||||
auto tabbedColumn = (myColumn == Window::Column::First) ? Window::Column::Second : Window::Column::Third;
|
||||
return _tabbedSection->rectForFloatPlayer(tabbedColumn, playerColumn);
|
||||
}
|
||||
QRect HistoryWidget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
@ -3827,7 +3691,7 @@ bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
||||
auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
|
||||
auto nametop = st::topBarArrowPadding.top();
|
||||
auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
|
||||
auto namewidth = _chatWidth - decreaseWidth - nameleft - st::topBarArrowPadding.right();
|
||||
auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
|
||||
p.setFont(st::dialogsTextFont);
|
||||
if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
|
||||
p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
|
||||
@ -3888,113 +3752,66 @@ void HistoryWidget::onModerateKeyActivate(int index, bool *outHandled) {
|
||||
void HistoryWidget::topBarClick() {
|
||||
if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
|
||||
App::main()->showBackFromStack();
|
||||
} else {
|
||||
if (_history) Ui::showPeerProfile(_peer);
|
||||
} else if (_peer) {
|
||||
controller()->showPeerInfo(_peer);
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::updateTabbedSelectorSectionShown() {
|
||||
auto tabbedSelectorSectionEnabled = Auth().data().tabbedSelectorSectionEnabled();
|
||||
auto useTabbedSection = tabbedSelectorSectionEnabled && (width() >= minimalWidthForTabbedSelectorSection());
|
||||
if (_tabbedSectionUsed == useTabbedSection) {
|
||||
void HistoryWidget::pushTabbedSelectorToThirdSection() {
|
||||
if (!_history || !_tabbedPanel) {
|
||||
return;
|
||||
}
|
||||
_tabbedSectionUsed = useTabbedSection;
|
||||
_tabbedSelectorToggle->setColorOverrides(
|
||||
&st::historyAttachEmojiActive,
|
||||
&st::historyRecordVoiceFgActive,
|
||||
&st::historyRecordVoiceRippleBgActive);
|
||||
auto destroyingPanel = std::move(_tabbedPanel);
|
||||
controller()->resizeForThirdSection();
|
||||
controller()->showSection(ChatHelpers::TabbedMemento(
|
||||
destroyingPanel->takeSelector(),
|
||||
base::lambda_guarded(this, [this](
|
||||
object_ptr<TabbedSelector> selector) {
|
||||
returnTabbedSelector(std::move(selector));
|
||||
})));
|
||||
}
|
||||
|
||||
// Use a separate bool flag instead of just (_tabbedSection != nullptr), because
|
||||
// _tabbedPanel->takeSelector() calls QWidget::render(), which calls
|
||||
// sendPendingMoveAndResizeEvents() for all widgets in the window, which can lead
|
||||
// to a new HistoryWidget::resizeEvent() call and an infinite recursion here.
|
||||
if (_tabbedSectionUsed) {
|
||||
_tabbedSection.create(this, controller(), _tabbedPanel->takeSelector());
|
||||
_tabbedSection->setCancelledCallback([this] { setInnerFocus(); });
|
||||
_tabbedSelectorToggle->setColorOverrides(&st::historyAttachEmojiActive, &st::historyRecordVoiceFgActive, &st::historyRecordVoiceRippleBgActive);
|
||||
_rightShadow.create(this, st::shadowFg);
|
||||
auto destroyingPanel = std::move(_tabbedPanel);
|
||||
updateControlsVisibility();
|
||||
} else {
|
||||
_tabbedPanel.create(this, controller(), _tabbedSection->takeSelector());
|
||||
_tabbedPanel->hide();
|
||||
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
|
||||
_tabbedSection.destroy();
|
||||
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
|
||||
_rightShadow.destroy();
|
||||
_tabbedSelectorToggleTooltipShown = false;
|
||||
void HistoryWidget::pushInfoToThirdSection() {
|
||||
if (!_peer) {
|
||||
return;
|
||||
}
|
||||
checkTabbedSelectorToggleTooltip();
|
||||
orderWidgets();
|
||||
}
|
||||
|
||||
void HistoryWidget::checkTabbedSelectorToggleTooltip() {
|
||||
if (_tabbedSection && !_tabbedSection->isHidden() && !_tabbedSelectorToggle->isHidden()) {
|
||||
if (!_tabbedSelectorToggleTooltipShown) {
|
||||
auto shownCount = Auth().data().tabbedSelectorSectionTooltipShown();
|
||||
if (shownCount < kTabbedSelectorToggleTooltipCount) {
|
||||
_tabbedSelectorToggleTooltipShown = true;
|
||||
_tabbedSelectorToggleTooltip.create(this, object_ptr<Ui::FlatLabel>(this, lang(lng_emoji_hide_panel), Ui::FlatLabel::InitType::Simple, st::defaultImportantTooltipLabel), st::defaultImportantTooltip);
|
||||
_tabbedSelectorToggleTooltip->setHiddenCallback([this] {
|
||||
_tabbedSelectorToggleTooltip.destroy();
|
||||
});
|
||||
InvokeQueued(_tabbedSelectorToggleTooltip, [this, shownCount] {
|
||||
Auth().data().setTabbedSelectorSectionTooltipShown(shownCount + 1);
|
||||
Auth().saveDataDelayed(kTabbedSelectorToggleTooltipTimeoutMs);
|
||||
|
||||
updateTabbedSelectorToggleTooltipGeometry();
|
||||
_tabbedSelectorToggleTooltip->hideAfter(kTabbedSelectorToggleTooltipTimeoutMs);
|
||||
_tabbedSelectorToggleTooltip->toggleAnimated(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_tabbedSelectorToggleTooltip.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
int HistoryWidget::tabbedSelectorSectionWidth() const {
|
||||
return st::emojiPanWidth;
|
||||
}
|
||||
|
||||
int HistoryWidget::minimalWidthForTabbedSelectorSection() const {
|
||||
return st::windowMinWidth + tabbedSelectorSectionWidth();
|
||||
}
|
||||
|
||||
bool HistoryWidget::willSwitchToTabbedSelectorWithWidth(int newWidth) const {
|
||||
if (!Auth().data().tabbedSelectorSectionEnabled()) {
|
||||
return false;
|
||||
} else if (_tabbedSectionUsed) {
|
||||
return false;
|
||||
}
|
||||
return (newWidth >= minimalWidthForTabbedSelectorSection());
|
||||
controller()->showPeerInfo(_peer);
|
||||
}
|
||||
|
||||
void HistoryWidget::toggleTabbedSelectorMode() {
|
||||
if (_tabbedSection) {
|
||||
Auth().data().setTabbedSelectorSectionEnabled(false);
|
||||
Auth().saveDataDelayed(kSaveTabbedSelectorSectionTimeoutMs);
|
||||
updateTabbedSelectorSectionShown();
|
||||
recountChatWidth();
|
||||
updateControlsGeometry();
|
||||
} else if (controller()->canProvideChatWidth(minimalWidthForTabbedSelectorSection())) {
|
||||
if (!Auth().data().tabbedSelectorSectionEnabled()) {
|
||||
if (_tabbedPanel) {
|
||||
if (controller()->canShowThirdSection()) {
|
||||
Auth().data().setTabbedSelectorSectionEnabled(true);
|
||||
Auth().saveDataDelayed(kSaveTabbedSelectorSectionTimeoutMs);
|
||||
pushTabbedSelectorToThirdSection();
|
||||
} else {
|
||||
_tabbedPanel->toggleAnimated();
|
||||
}
|
||||
controller()->provideChatWidth(minimalWidthForTabbedSelectorSection());
|
||||
updateTabbedSelectorSectionShown();
|
||||
recountChatWidth();
|
||||
updateControlsGeometry();
|
||||
} else {
|
||||
Assert(_tabbedPanel != nullptr);
|
||||
_tabbedPanel->toggleAnimated();
|
||||
controller()->closeThirdSection();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::returnTabbedSelector(
|
||||
object_ptr<TabbedSelector> selector) {
|
||||
_tabbedPanel.create(
|
||||
this,
|
||||
controller(),
|
||||
std::move(selector));
|
||||
_tabbedPanel->hide();
|
||||
_tabbedSelectorToggle->installEventFilter(_tabbedPanel);
|
||||
_tabbedSelectorToggle->setColorOverrides(nullptr, nullptr, nullptr);
|
||||
_tabbedSelectorToggleTooltipShown = false;
|
||||
}
|
||||
|
||||
void HistoryWidget::recountChatWidth() {
|
||||
_chatWidth = width();
|
||||
if (_tabbedSection) {
|
||||
_chatWidth -= _tabbedSection->width();
|
||||
}
|
||||
auto layout = (_chatWidth < st::adaptiveChatWideWidth) ? Adaptive::ChatLayout::Normal : Adaptive::ChatLayout::Wide;
|
||||
auto layout = (width() < st::adaptiveChatWideWidth)
|
||||
? Adaptive::ChatLayout::Normal
|
||||
: Adaptive::ChatLayout::Wide;
|
||||
if (layout != Global::AdaptiveChatLayout()) {
|
||||
Global::SetAdaptiveChatLayout(layout);
|
||||
Adaptive::Changed().notify(true);
|
||||
@ -4106,11 +3923,11 @@ void HistoryWidget::moveFieldControls() {
|
||||
auto keyboardHeight = 0;
|
||||
auto bottom = height();
|
||||
auto maxKeyboardHeight = st::historyComposeFieldMaxHeight - _field->height();
|
||||
_keyboard->resizeToWidth(_chatWidth, maxKeyboardHeight);
|
||||
_keyboard->resizeToWidth(width(), maxKeyboardHeight);
|
||||
if (_kbShown) {
|
||||
keyboardHeight = qMin(_keyboard->height(), maxKeyboardHeight);
|
||||
bottom -= keyboardHeight;
|
||||
_kbScroll->setGeometryToLeft(0, bottom, _chatWidth, keyboardHeight);
|
||||
_kbScroll->setGeometryToLeft(0, bottom, width(), keyboardHeight);
|
||||
}
|
||||
|
||||
// _attachToggle --------- _inlineResults -------------------------------------- _tabbedPanel --------- _fieldBarCancel
|
||||
@ -4121,7 +3938,7 @@ void HistoryWidget::moveFieldControls() {
|
||||
auto left = 0;
|
||||
_attachToggle->moveToLeft(left, buttonsBottom); left += _attachToggle->width();
|
||||
_field->moveToLeft(left, bottom - _field->height() - st::historySendPadding);
|
||||
auto right = (width() - _chatWidth) + st::historySendRight;
|
||||
auto right = st::historySendRight;
|
||||
_send->moveToRight(right, buttonsBottom); right += _send->width();
|
||||
_tabbedSelectorToggle->moveToRight(right, buttonsBottom);
|
||||
updateTabbedSelectorToggleTooltipGeometry();
|
||||
@ -4130,7 +3947,7 @@ void HistoryWidget::moveFieldControls() {
|
||||
_botCommandStart->moveToRight(right, buttonsBottom);
|
||||
_silent->moveToRight(right, buttonsBottom);
|
||||
|
||||
_fieldBarCancel->moveToRight(width() - _chatWidth, _field->y() - st::historySendPadding - _fieldBarCancel->height());
|
||||
_fieldBarCancel->moveToRight(0, _field->y() - st::historySendPadding - _fieldBarCancel->height());
|
||||
if (_inlineResults) {
|
||||
_inlineResults->moveBottom(_field->y() - st::historySendPadding);
|
||||
}
|
||||
@ -4138,7 +3955,11 @@ void HistoryWidget::moveFieldControls() {
|
||||
_tabbedPanel->moveBottom(buttonsBottom);
|
||||
}
|
||||
|
||||
auto fullWidthButtonRect = myrtlrect(0, bottom - _botStart->height(), _chatWidth, _botStart->height());
|
||||
auto fullWidthButtonRect = myrtlrect(
|
||||
0,
|
||||
bottom - _botStart->height(),
|
||||
width(),
|
||||
_botStart->height());
|
||||
_botStart->setGeometry(fullWidthButtonRect);
|
||||
_unblock->setGeometry(fullWidthButtonRect);
|
||||
_joinChannel->setGeometry(fullWidthButtonRect);
|
||||
@ -4156,7 +3977,7 @@ void HistoryWidget::updateTabbedSelectorToggleTooltipGeometry() {
|
||||
|
||||
void HistoryWidget::updateFieldSize() {
|
||||
auto kbShowShown = _history && !_kbShown && _keyboard->hasMarkup();
|
||||
auto fieldWidth = _chatWidth - _attachToggle->width() - st::historySendRight;
|
||||
auto fieldWidth = width() - _attachToggle->width() - st::historySendRight;
|
||||
fieldWidth -= _send->width();
|
||||
fieldWidth -= _tabbedSelectorToggle->width();
|
||||
if (kbShowShown) fieldWidth -= _botKeyboardShow->width();
|
||||
@ -4780,31 +4601,28 @@ void HistoryWidget::handlePendingHistoryUpdate() {
|
||||
}
|
||||
|
||||
void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||
updateTabbedSelectorSectionShown();
|
||||
//updateTabbedSelectorSectionShown();
|
||||
recountChatWidth();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
void HistoryWidget::updateControlsGeometry() {
|
||||
if (_tabbedSection) {
|
||||
_tabbedSection->setGeometryToRight(0, 0, st::emojiPanWidth, height());
|
||||
}
|
||||
_topBar->setGeometryToLeft(0, 0, _chatWidth, st::topBarHeight);
|
||||
_topBar->setGeometryToLeft(0, 0, width(), st::topBarHeight);
|
||||
|
||||
moveFieldControls();
|
||||
|
||||
auto scrollAreaTop = _topBar->bottomNoMargins();
|
||||
if (_pinnedBar) {
|
||||
_pinnedBar->cancel->moveToLeft(_chatWidth - _pinnedBar->cancel->width(), scrollAreaTop);
|
||||
_pinnedBar->cancel->moveToLeft(width() - _pinnedBar->cancel->width(), scrollAreaTop);
|
||||
scrollAreaTop += st::historyReplyHeight;
|
||||
_pinnedBar->shadow->setGeometryToLeft(0, scrollAreaTop, _chatWidth, st::lineWidth);
|
||||
_pinnedBar->shadow->setGeometryToLeft(0, scrollAreaTop, width(), st::lineWidth);
|
||||
}
|
||||
if (_scroll->y() != scrollAreaTop) {
|
||||
_scroll->moveToLeft(0, scrollAreaTop);
|
||||
_fieldAutocomplete->setBoundings(_scroll->geometry());
|
||||
}
|
||||
if (_reportSpamPanel) {
|
||||
_reportSpamPanel->setGeometryToLeft(0, _scroll->y(), _chatWidth, _reportSpamPanel->height());
|
||||
_reportSpamPanel->setGeometryToLeft(0, _scroll->y(), width(), _reportSpamPanel->height());
|
||||
}
|
||||
|
||||
updateHistoryGeometry(false, false, { ScrollChangeAdd, App::main() ? App::main()->contentScrollAddToY() : 0 });
|
||||
@ -4834,12 +4652,13 @@ void HistoryWidget::updateControlsGeometry() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (_rightShadow) {
|
||||
_rightShadow->setGeometryToLeft(_chatWidth - st::lineWidth, 0, st::lineWidth, height());
|
||||
}
|
||||
auto topShadowLeft = (Adaptive::OneColumn() || _inGrab) ? 0 : st::lineWidth;
|
||||
auto topShadowRight = _rightShadow ? st::lineWidth : 0;
|
||||
_topShadow->setGeometryToLeft(topShadowLeft, _topBar->bottomNoMargins(), _chatWidth - topShadowLeft - topShadowRight, st::lineWidth);
|
||||
auto topShadowRight = (Adaptive::ThreeColumn() && !_inGrab && _peer) ? st::lineWidth : 0;
|
||||
_topShadow->setGeometryToLeft(
|
||||
topShadowLeft,
|
||||
_topBar->bottomNoMargins(),
|
||||
width() - topShadowLeft - topShadowRight,
|
||||
st::lineWidth);
|
||||
}
|
||||
|
||||
void HistoryWidget::itemRemoved(HistoryItem *item) {
|
||||
@ -4963,9 +4782,9 @@ void HistoryWidget::updateHistoryGeometry(bool initial, bool loadedDown, const S
|
||||
auto wasScrollTop = _scroll->scrollTop();
|
||||
auto wasScrollTopMax = _scroll->scrollTopMax();
|
||||
auto wasAtBottom = wasScrollTop + 1 > wasScrollTopMax;
|
||||
auto needResize = (_scroll->width() != _chatWidth) || (_scroll->height() != newScrollHeight);
|
||||
auto needResize = (_scroll->width() != width()) || (_scroll->height() != newScrollHeight);
|
||||
if (needResize) {
|
||||
_scroll->resize(_chatWidth, newScrollHeight);
|
||||
_scroll->resize(width(), newScrollHeight);
|
||||
// on initial updateListSize we didn't put the _scroll->scrollTop correctly yet
|
||||
// so visibleAreaUpdated() call will erase it with the new (undefined) value
|
||||
if (!initial) {
|
||||
@ -6379,7 +6198,7 @@ void HistoryWidget::updateReplyToName() {
|
||||
|
||||
void HistoryWidget::updateField() {
|
||||
auto fieldAreaTop = _scroll->y() + _scroll->height();
|
||||
rtlupdate(0, fieldAreaTop, _chatWidth, height() - fieldAreaTop);
|
||||
rtlupdate(0, fieldAreaTop, width(), height() - fieldAreaTop);
|
||||
}
|
||||
|
||||
void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
@ -6402,7 +6221,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
backh += st::historyReplyHeight;
|
||||
}
|
||||
auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
||||
p.fillRect(myrtlrect(0, backy, _chatWidth, backh), st::historyReplyBg);
|
||||
p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
|
||||
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
||||
auto replyLeft = st::historyReplySkip;
|
||||
(_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width());
|
||||
@ -6420,14 +6239,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
if (_editMsgId) {
|
||||
paintEditHeader(p, rect, replyLeft, backy);
|
||||
} else {
|
||||
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
}
|
||||
p.setPen(((drawMsgText->toHistoryMessage() && drawMsgText->toHistoryMessage()->emptyText()) || drawMsgText->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
|
||||
_replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
_replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
} else {
|
||||
p.setFont(st::msgDateFont);
|
||||
p.setPen(st::historyComposeAreaFgService);
|
||||
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), _chatWidth - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
|
||||
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
|
||||
}
|
||||
}
|
||||
} else if (hasForward) {
|
||||
@ -6451,7 +6270,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
p.setPen(st::historyReplyNameFg);
|
||||
_toForwardFrom.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top(), width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
p.setPen(serviceColor ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
|
||||
_toForwardText.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
_toForwardText.drawElided(p, forwardLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - forwardLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
}
|
||||
}
|
||||
if (drawWebPagePreview) {
|
||||
@ -6471,14 +6290,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||
}
|
||||
p.setPen(st::historyReplyNameFg);
|
||||
_previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), _chatWidth - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
_previewTitle.drawElided(p, previewLeft, backy + st::msgReplyPadding.top(), width() - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
p.setPen(st::historyComposeAreaFg);
|
||||
_previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, _chatWidth - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
_previewDescription.drawElided(p, previewLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - previewLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::drawRestrictedWrite(Painter &p) {
|
||||
auto rect = myrtlrect(0, height() - _unblock->height(), _chatWidth, _unblock->height());
|
||||
auto rect = myrtlrect(0, height() - _unblock->height(), width(), _unblock->height());
|
||||
p.fillRect(rect, st::historyReplyBg);
|
||||
|
||||
p.setFont(st::normalFont);
|
||||
@ -6487,7 +6306,7 @@ void HistoryWidget::drawRestrictedWrite(Painter &p) {
|
||||
}
|
||||
|
||||
void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int top) const {
|
||||
if (!rect.intersects(myrtlrect(left, top, _chatWidth - left, st::normalFont->height))) {
|
||||
if (!rect.intersects(myrtlrect(left, top, width() - left, st::normalFont->height))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6517,7 +6336,7 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
|
||||
}
|
||||
|
||||
// Restart timer only if we are sure that we've painted the whole timer.
|
||||
if (rect.contains(myrtlrect(left, top, _chatWidth - left, st::normalFont->height)) && updateIn > 0) {
|
||||
if (rect.contains(myrtlrect(left, top, width() - left, st::normalFont->height)) && updateIn > 0) {
|
||||
_updateEditTimeLeftDisplay.start(updateIn);
|
||||
}
|
||||
|
||||
@ -6546,7 +6365,7 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
||||
p.drawText(_attachToggle->x() + _tabbedSelectorToggle->width(), _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, duration);
|
||||
|
||||
int32 left = _attachToggle->x() + _tabbedSelectorToggle->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2);
|
||||
int32 right = _chatWidth - _send->width();
|
||||
int32 right = width() - _send->width();
|
||||
|
||||
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
|
||||
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, lang(lng_record_cancel));
|
||||
@ -6559,7 +6378,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
Text *from = 0, *text = 0;
|
||||
bool serviceColor = false, hasForward = readyToForward();
|
||||
ImagePtr preview;
|
||||
p.fillRect(myrtlrect(0, top, _chatWidth, st::historyReplyHeight), st::historyPinnedBg);
|
||||
p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||
|
||||
top += st::msgReplyPadding.top();
|
||||
QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||
@ -6580,11 +6399,11 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message));
|
||||
|
||||
p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg);
|
||||
_pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, _chatWidth - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||
_pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||
} else {
|
||||
p.setFont(st::msgDateFont);
|
||||
p.setPen(st::historyComposeAreaFgService);
|
||||
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), _chatWidth - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
|
||||
p.drawText(left, top + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(lang(lng_profile_loading), width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -6607,7 +6426,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||
_unreadMentionsShown.step(ms);
|
||||
auto progress = _a_show.current(ms, 1.);
|
||||
if (_a_show.animating()) {
|
||||
auto animationWidth = (!_tabbedSection || _tabbedSection->isHidden()) ? width() : _chatWidth;
|
||||
auto animationWidth = width();
|
||||
auto retina = cIntRetinaFactor();
|
||||
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
|
||||
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||
@ -6625,7 +6444,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||
return;
|
||||
}
|
||||
|
||||
QRect fill(0, 0, _history ? _chatWidth : width(), App::main()->height());
|
||||
QRect fill(0, 0, width(), App::main()->height());
|
||||
auto fromy = App::main()->backgroundFromY();
|
||||
auto x = 0, y = 0;
|
||||
QPixmap cached = App::main()->cachedBackground(fill, x, y);
|
||||
|
@ -207,15 +207,13 @@ public:
|
||||
void unreadCountChanged(History *history);
|
||||
|
||||
QRect historyRect() const;
|
||||
int tabbedSelectorSectionWidth() const;
|
||||
int minimalWidthForTabbedSelectorSection() const;
|
||||
bool willSwitchToTabbedSelectorWithWidth(int newWidth) const;
|
||||
void pushTabbedSelectorToThirdSection();
|
||||
void pushInfoToThirdSection();
|
||||
|
||||
void updateSendAction(History *history, SendAction::Type type, int32 progress = 0);
|
||||
void cancelSendAction(History *history, SendAction::Type type);
|
||||
|
||||
void updateRecentStickers();
|
||||
void stickersInstalled(uint64 setId);
|
||||
void sendActionDone(const MTPBool &result, mtpRequestId req);
|
||||
|
||||
void destroyData();
|
||||
@ -347,8 +345,8 @@ public:
|
||||
void deleteSelectedItems(bool forEveryone);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, not_null<const HistoryItem*> msg, int row, int col);
|
||||
|
||||
@ -479,12 +477,14 @@ private:
|
||||
QStringList filesToSend;
|
||||
bool allFilesForCompress = true;
|
||||
};
|
||||
using TabbedPanel = ChatHelpers::TabbedPanel;
|
||||
using TabbedSelector = ChatHelpers::TabbedSelector;
|
||||
|
||||
void handlePendingHistoryUpdate();
|
||||
void fullPeerUpdated(PeerData *peer);
|
||||
void topBarClick();
|
||||
void toggleTabbedSelectorMode();
|
||||
void updateTabbedSelectorSectionShown();
|
||||
void returnTabbedSelector(object_ptr<TabbedSelector> selector);
|
||||
void recountChatWidth();
|
||||
void setReportSpamStatus(DBIPeerReportSpamStatus status);
|
||||
void historyDownClicked();
|
||||
@ -562,7 +562,6 @@ private:
|
||||
int _toForwardNameVersion = 0;
|
||||
int _forwardingItemRemovedSubscription = 0;
|
||||
|
||||
int _chatWidth = 0;
|
||||
MsgId _editMsgId = 0;
|
||||
|
||||
HistoryItem *_replyEditMsg = nullptr;
|
||||
@ -822,10 +821,8 @@ private:
|
||||
QTimer _membersDropdownShowTimer;
|
||||
|
||||
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
|
||||
object_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
|
||||
object_ptr<ChatHelpers::TabbedSection> _tabbedSection = { nullptr };
|
||||
QPointer<ChatHelpers::TabbedSelector> _tabbedSelector;
|
||||
bool _tabbedSectionUsed = false;
|
||||
object_ptr<TabbedPanel> _tabbedPanel;
|
||||
QPointer<TabbedSelector> _tabbedSelector;
|
||||
DragState _attachDrag = DragStateNone;
|
||||
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
|
||||
|
||||
@ -863,7 +860,6 @@ private:
|
||||
QTimer _saveDraftTimer, _saveCloudDraftTimer;
|
||||
|
||||
object_ptr<Ui::PlainShadow> _topShadow;
|
||||
object_ptr<Ui::PlainShadow> _rightShadow = { nullptr };
|
||||
bool _inGrab = false;
|
||||
|
||||
};
|
||||
|
@ -106,7 +106,7 @@ void LayerWrap::parentResized() {
|
||||
hide();
|
||||
setParent(nullptr);
|
||||
auto localCopy = _controller;
|
||||
localCopy->showWideSection(
|
||||
localCopy->showSection(
|
||||
MoveMemento(std::move(_content), Wrap::Narrow));
|
||||
localCopy->hideSpecialLayer(LayerOption::ForceFast);
|
||||
} else {
|
||||
|
@ -30,14 +30,6 @@ InnerWidget::InnerWidget(
|
||||
: RpWidget(parent)
|
||||
, _peer(peer)
|
||||
, _type(type) {
|
||||
base::lambda<void(int)> launch = [this, &launch](int counter) {
|
||||
QTimer::singleShot(500, this, [this, launch, counter] {
|
||||
_rowsHeightFake += 300;
|
||||
resizeToWidth(width(), _minHeight);
|
||||
launch(counter - 1);
|
||||
});
|
||||
};
|
||||
launch(10);
|
||||
}
|
||||
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
|
@ -165,7 +165,14 @@ std::unique_ptr<ContentMemento> Memento::Default(
|
||||
object_ptr<Window::SectionWidget> Memento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
if (column == Window::Column::Third) {
|
||||
return object_ptr<SideWrap>(
|
||||
parent,
|
||||
controller,
|
||||
this);
|
||||
}
|
||||
return object_ptr<NarrowWrap>(
|
||||
parent,
|
||||
controller,
|
||||
@ -193,21 +200,24 @@ MoveMemento::MoveMemento(
|
||||
object_ptr<Window::SectionWidget> MoveMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
if (_wrap == Wrap::Narrow) {
|
||||
if (_wrap == Wrap::Narrow && column != Window::Column::Third) {
|
||||
auto result = object_ptr<NarrowWrap>(
|
||||
parent,
|
||||
controller,
|
||||
this);
|
||||
result->setGeometry(geometry);
|
||||
return result;
|
||||
} else if (_wrap == Wrap::Side && column == Window::Column::Third) {
|
||||
auto result = object_ptr<SideWrap>(
|
||||
parent,
|
||||
controller,
|
||||
this);
|
||||
result->setGeometry(geometry);
|
||||
return result;
|
||||
}
|
||||
auto result = object_ptr<SideWrap>(
|
||||
parent,
|
||||
controller,
|
||||
this);
|
||||
result->setGeometry(geometry);
|
||||
return result;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
object_ptr<LayerWidget> MoveMemento::createLayer(
|
||||
|
@ -195,6 +195,7 @@ public:
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
object_ptr<LayerWidget> createLayer(
|
||||
@ -232,6 +233,7 @@ public:
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
object_ptr<LayerWidget> createLayer(
|
||||
|
@ -176,20 +176,20 @@ void NarrowWrap::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
|
||||
void NarrowWrap::paintEvent(QPaintEvent *e) {
|
||||
SectionWidget::paintEvent(e);
|
||||
if (animating()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Painter p(this);
|
||||
p.fillRect(e->rect(), st::profileBg);
|
||||
}
|
||||
|
||||
bool NarrowWrap::wheelEventFromFloatPlayer(
|
||||
QEvent *e,
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) {
|
||||
bool NarrowWrap::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _content->wheelEventFromFloatPlayer(e);
|
||||
}
|
||||
|
||||
QRect NarrowWrap::rectForFloatPlayer(
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) const {
|
||||
QRect NarrowWrap::rectForFloatPlayer() const {
|
||||
return _content->rectForFloatPlayer();
|
||||
}
|
||||
|
||||
|
@ -79,13 +79,8 @@ public:
|
||||
not_null<Memento*> memento);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(
|
||||
QEvent *e,
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "info/info_media_widget.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "ui/widgets/discrete_sliders.h"
|
||||
#include "auth_session.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_info.h"
|
||||
@ -80,8 +81,7 @@ void SideWrap::showTab(Tab tab) {
|
||||
showContent(createContent(tab));
|
||||
}
|
||||
|
||||
void SideWrap::showContent(object_ptr<ContentWidget> content) {
|
||||
auto section = content->section();
|
||||
void SideWrap::setSection(const Section §ion) {
|
||||
switch (section.type()) {
|
||||
case Section::Type::Profile:
|
||||
setCurrentTab(Tab::Profile);
|
||||
@ -102,7 +102,9 @@ void SideWrap::showContent(object_ptr<ContentWidget> content) {
|
||||
setCurrentTab(Tab::None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SideWrap::showContent(object_ptr<ContentWidget> content) {
|
||||
_content = std::move(content);
|
||||
_content->setGeometry(contentGeometry());
|
||||
_content->show();
|
||||
@ -158,6 +160,9 @@ void SideWrap::doSetInnerFocus() {
|
||||
_content->setInnerFocus();
|
||||
}
|
||||
|
||||
void SideWrap::showFinishedHook() {
|
||||
}
|
||||
|
||||
bool SideWrap::showInternal(
|
||||
not_null<Window::SectionMemento*> memento) {
|
||||
if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||
@ -203,6 +208,8 @@ QRect SideWrap::contentGeometry() const {
|
||||
}
|
||||
|
||||
void SideWrap::restoreState(not_null<Memento*> memento) {
|
||||
// Validates contentGeometry().
|
||||
setSection(memento->section());
|
||||
showContent(memento->content()->createWidget(
|
||||
this,
|
||||
Wrap::Side,
|
||||
@ -211,7 +218,9 @@ void SideWrap::restoreState(not_null<Memento*> memento) {
|
||||
}
|
||||
|
||||
void SideWrap::restoreState(not_null<MoveMemento*> memento) {
|
||||
showContent(memento->content(this, Wrap::Side));
|
||||
auto content = memento->content(this, Wrap::Side);
|
||||
setSection(content->section());
|
||||
showContent(std::move(content));
|
||||
}
|
||||
|
||||
void SideWrap::setCurrentTab(Tab tab) {
|
||||
@ -235,20 +244,20 @@ void SideWrap::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
|
||||
void SideWrap::paintEvent(QPaintEvent *e) {
|
||||
SectionWidget::paintEvent(e);
|
||||
if (animating()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Painter p(this);
|
||||
p.fillRect(e->rect(), st::profileBg);
|
||||
}
|
||||
|
||||
bool SideWrap::wheelEventFromFloatPlayer(
|
||||
QEvent *e,
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) {
|
||||
bool SideWrap::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _content->wheelEventFromFloatPlayer(e);
|
||||
}
|
||||
|
||||
QRect SideWrap::rectForFloatPlayer(
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) const {
|
||||
QRect SideWrap::rectForFloatPlayer() const {
|
||||
return _content->rectForFloatPlayer();
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ namespace Media {
|
||||
class Widget;
|
||||
} // namespace Media
|
||||
|
||||
class Section;
|
||||
class Memento;
|
||||
class MoveMemento;
|
||||
class ContentWidget;
|
||||
@ -75,19 +76,15 @@ public:
|
||||
not_null<Memento*> memento);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(
|
||||
QEvent *e,
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(
|
||||
Window::Column myColumn,
|
||||
Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void doSetInnerFocus() override;
|
||||
void showFinishedHook() override;
|
||||
|
||||
private:
|
||||
enum class Tab {
|
||||
@ -105,6 +102,7 @@ private:
|
||||
void setupTabs();
|
||||
void showTab(Tab tab);
|
||||
void setCurrentTab(Tab tab);
|
||||
void setSection(const Section §ion);
|
||||
void showContent(object_ptr<ContentWidget> content);
|
||||
object_ptr<ContentWidget> createContent(Tab tab);
|
||||
object_ptr<Profile::Widget> createProfileWidget();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -156,7 +156,8 @@ class MainWidget : public Ui::RpWidget, public RPCSender, private base::Subscrib
|
||||
public:
|
||||
MainWidget(QWidget *parent, not_null<Window::Controller*> controller);
|
||||
|
||||
bool isSectionShown() const;
|
||||
bool isMainSectionShown() const;
|
||||
bool isThirdSectionShown() const;
|
||||
|
||||
// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
|
||||
bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms);
|
||||
@ -212,14 +213,17 @@ public:
|
||||
int backgroundFromY() const;
|
||||
PeerData *overviewPeer();
|
||||
bool showMediaTypeSwitch() const;
|
||||
void showWideSection(Window::SectionMemento &&memento);
|
||||
void showSection(
|
||||
Window::SectionMemento &&memento,
|
||||
anim::type animated);
|
||||
void updateColumnLayout();
|
||||
void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1);
|
||||
bool stackIsEmpty() const;
|
||||
void showBackFromStack();
|
||||
void orderWidgets();
|
||||
QRect historyRect() const;
|
||||
QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms);
|
||||
void checkWideSectionToLayer();
|
||||
void checkMainSectionToLayer();
|
||||
|
||||
void onSendFileConfirm(const FileLoadResultPtr &file);
|
||||
bool onSendSticker(DocumentData *sticker);
|
||||
@ -442,8 +446,6 @@ public slots:
|
||||
|
||||
void onUpdateMuted();
|
||||
|
||||
void onStickersInstalled(uint64 setId);
|
||||
|
||||
void onViewsIncrement();
|
||||
|
||||
void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way);
|
||||
@ -523,12 +525,19 @@ private:
|
||||
mtpRequestId req);
|
||||
void mediaOverviewUpdated(const Notify::PeerUpdate &update);
|
||||
|
||||
Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow, bool willHaveTabbedSection);
|
||||
void showNewWideSection(Window::SectionMemento &&memento, bool back, bool saveInStack);
|
||||
void dropWideSection(Window::SectionWidget *widget);
|
||||
Window::SectionSlideParams prepareShowAnimation(
|
||||
bool willHaveTopBarShadow);
|
||||
void showNewSection(
|
||||
Window::SectionMemento &&memento,
|
||||
bool back,
|
||||
bool saveInStack,
|
||||
anim::type animated);
|
||||
void dropMainSection(Window::SectionWidget *widget);
|
||||
|
||||
Window::SectionSlideParams prepareThirdSectionAnimation(Window::SectionWidget *section);
|
||||
|
||||
// All this methods use the prepareShowAnimation().
|
||||
Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section);
|
||||
Window::SectionSlideParams prepareMainSectionAnimation(Window::SectionWidget *section);
|
||||
Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId);
|
||||
Window::SectionSlideParams prepareOverviewAnimation();
|
||||
Window::SectionSlideParams prepareDialogsAnimation();
|
||||
@ -564,7 +573,8 @@ private:
|
||||
void inviteImportDone(const MTPUpdates &result);
|
||||
bool inviteImportFail(const RPCError &error);
|
||||
|
||||
int getSectionTop() const;
|
||||
int getMainSectionTop() const;
|
||||
int getThirdSectionTop() const;
|
||||
|
||||
void hideAll();
|
||||
void showAll();
|
||||
@ -581,11 +591,17 @@ private:
|
||||
Float *currentFloatPlayer() const {
|
||||
return _playerFloats.empty() ? nullptr : _playerFloats.back().get();
|
||||
}
|
||||
Window::AbstractSectionWidget *getFloatPlayerSection(not_null<Window::Column*> column) const;
|
||||
void finishFloatPlayerDrag(not_null<Float*> instance, bool closed);
|
||||
Window::AbstractSectionWidget *getFloatPlayerSection(
|
||||
Window::Column column) const;
|
||||
void finishFloatPlayerDrag(
|
||||
not_null<Float*> instance,
|
||||
bool closed);
|
||||
void updateFloatPlayerColumnCorner(QPoint center);
|
||||
QPoint getFloatPlayerPosition(not_null<Float*> instance) const;
|
||||
QPoint getFloatPlayerHiddenPosition(QPoint position, QSize size, RectPart side) const;
|
||||
QPoint getFloatPlayerHiddenPosition(
|
||||
QPoint position,
|
||||
QSize size,
|
||||
RectPart side) const;
|
||||
RectPart getFloatPlayerSide(QPoint center) const;
|
||||
|
||||
bool ptsUpdateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
|
||||
@ -615,10 +631,11 @@ private:
|
||||
Animation _a_dialogsWidth;
|
||||
|
||||
object_ptr<Ui::PlainShadow> _sideShadow;
|
||||
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
|
||||
object_ptr<TWidget> _sideResizeArea;
|
||||
object_ptr<DialogsWidget> _dialogs;
|
||||
object_ptr<HistoryWidget> _history;
|
||||
object_ptr<Window::SectionWidget> _wideSection = { nullptr };
|
||||
object_ptr<Window::SectionWidget> _mainSection = { nullptr };
|
||||
object_ptr<Window::SectionWidget> _thirdSection = { nullptr };
|
||||
object_ptr<OverviewWidget> _overview = { nullptr };
|
||||
|
||||
|
@ -812,7 +812,7 @@ void MainWindow::updateControlsGeometry() {
|
||||
if (_connecting) _connecting->moveToLeft(0, body.height() - _connecting->height());
|
||||
if (_testingThemeWarning) _testingThemeWarning->setGeometry(body);
|
||||
|
||||
if (_main) _main->checkWideSectionToLayer();
|
||||
if (_main) _main->checkMainSectionToLayer();
|
||||
}
|
||||
|
||||
MainWindow::TempDirState MainWindow::tempDirState() {
|
||||
|
@ -62,7 +62,7 @@ OverviewInner::OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, P
|
||||
, _search(this, st::overviewFilter, langFactory(lng_dlg_filter))
|
||||
, _cancelSearch(this, st::dialogsCancelSearch)
|
||||
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
||||
, _width(st::windowMinWidth) {
|
||||
, _width(st::columnMinimalWidthMain) {
|
||||
subscribe(Auth().downloader().taskFinished(), [this] { update(); });
|
||||
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||
itemRemoved(item);
|
||||
@ -1314,7 +1314,7 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
|
||||
contentLeftMin -= st::overviewFileLayout.songPadding.left();
|
||||
contentLeftMax -= st::overviewFileLayout.songPadding.left();
|
||||
}
|
||||
auto widthWithMin = st::windowMinWidth;
|
||||
auto widthWithMin = st::columnMinimalWidthMain;
|
||||
auto widthWithMax = st::overviewFileLayout.maxWidth + 2 * contentLeftMax;
|
||||
_rowsLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - _width, 0) / float64(widthWithMax - widthWithMin));
|
||||
_rowWidth = qMin(_width - 2 * _rowsLeft, st::overviewFileLayout.maxWidth);
|
||||
@ -2145,11 +2145,11 @@ int32 OverviewWidget::lastScrollTop() const {
|
||||
return _scroll->scrollTop();
|
||||
}
|
||||
|
||||
bool OverviewWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool OverviewWidget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect OverviewWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect OverviewWidget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -349,8 +349,8 @@ public:
|
||||
void deleteSelectedItems(bool forEveryone);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
void ui_repaintHistoryItem(not_null<const HistoryItem*> item);
|
||||
|
||||
|
@ -156,7 +156,7 @@ void ChannelMembersWidget::onAdmins() {
|
||||
void ChannelMembersWidget::onRecentActions() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (auto main = App::main()) {
|
||||
main->showWideSection(AdminLog::SectionMemento(channel));
|
||||
main->showSection(AdminLog::SectionMemento(channel), anim::type::normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ void SettingsWidget::onManageAdmins() {
|
||||
void SettingsWidget::onRecentActions() {
|
||||
if (auto channel = peer()->asChannel()) {
|
||||
if (auto main = App::main()) {
|
||||
main->showWideSection(AdminLog::SectionMemento(channel));
|
||||
main->showSection(AdminLog::SectionMemento(channel), anim::type::normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ void SharedMediaWidget::onShowCommonGroups() {
|
||||
return;
|
||||
}
|
||||
if (auto main = App::main()) {
|
||||
main->showWideSection(Profile::CommonGroups::SectionMemento(peer()->asUser()));
|
||||
main->showSection(Profile::CommonGroups::SectionMemento(peer()->asUser()), anim::type::normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,11 @@ constexpr int kCommonGroupsPerPage = 40;
|
||||
|
||||
} // namespace
|
||||
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) {
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
auto result = object_ptr<Widget>(parent, controller, _user);
|
||||
result->setInternalState(geometry, this);
|
||||
return std::move(result);
|
||||
@ -196,7 +200,7 @@ int InnerWidget::resizeGetHeight(int newWidth) {
|
||||
|
||||
auto contentLeftMin = st::profileCommonGroupsLeftMin;
|
||||
auto contentLeftMax = st::profileCommonGroupsLeftMax;
|
||||
auto widthWithMin = st::windowMinWidth;
|
||||
auto widthWithMin = st::columnMinimalWidthMain;
|
||||
auto widthWithMax = st::profileCommonGroupsWidthMax + 2 * contentLeftMax;
|
||||
_contentLeft = anim::interpolate(contentLeftMax, contentLeftMin, qMax(widthWithMax - newWidth, 0) / float64(widthWithMax - widthWithMin));
|
||||
_contentWidth = qMin(newWidth - 2 * _contentLeft, st::profileCommonGroupsWidthMax);
|
||||
@ -447,11 +451,11 @@ void Widget::showFinishedHook() {
|
||||
_fixedBar->setAnimatingMode(false);
|
||||
}
|
||||
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect Widget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,11 @@ public:
|
||||
SectionMemento(not_null<UserData*> user) : _user(user) {
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override;
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
not_null<UserData*> getUser() const {
|
||||
return _user;
|
||||
@ -189,8 +193,8 @@ public:
|
||||
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
@ -117,7 +117,7 @@ void CoverWidget::onCancelPhotoUpload() {
|
||||
|
||||
int CoverWidget::countPhotoLeft(int newWidth) const {
|
||||
int result = st::profilePhotoLeftMin;
|
||||
result += (newWidth - st::windowMinWidth) / 2;
|
||||
result += (newWidth - st::columnMinimalWidthMain) / 2;
|
||||
return qMin(result, st::profilePhotoLeftMax);
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ int InnerWidget::countBlocksHeight(RectPart countSide) const {
|
||||
|
||||
int InnerWidget::countBlocksLeft(int newWidth) const {
|
||||
int result = st::profileBlockLeftMin;
|
||||
result += (newWidth - st::windowMinWidth) / 2;
|
||||
result += (newWidth - st::columnMinimalWidthMain) / 2;
|
||||
return qMin(result, st::profileBlockLeftMax);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace Profile {
|
||||
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) {
|
||||
object_ptr<Window::SectionWidget> SectionMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) {
|
||||
auto result = object_ptr<Widget>(parent, controller, _peer);
|
||||
result->setInternalState(geometry, this);
|
||||
return std::move(result);
|
||||
|
@ -31,7 +31,11 @@ public:
|
||||
SectionMemento(PeerData *peer) : _peer(peer) {
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(QWidget *parent, not_null<Window::Controller*> controller, const QRect &geometry) override;
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Window::Column column,
|
||||
const QRect &geometry) override;
|
||||
|
||||
PeerData *getPeer() const {
|
||||
return _peer;
|
||||
|
@ -161,11 +161,11 @@ void Widget::showFinishedHook() {
|
||||
_inner->showFinished();
|
||||
}
|
||||
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
bool Widget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
QRect Widget::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,8 @@ public:
|
||||
void setInternalState(const QRect &geometry, not_null<SectionMemento*> memento);
|
||||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||
QRect rectForFloatPlayer() const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
@ -93,6 +93,11 @@ enum Notification {
|
||||
|
||||
namespace anim {
|
||||
|
||||
enum class type {
|
||||
normal,
|
||||
instant,
|
||||
};
|
||||
|
||||
using transition = base::lambda<float64(float64 delta, float64 dt)>;
|
||||
|
||||
extern transition linear;
|
||||
|
@ -191,8 +191,6 @@ QPixmap myGrab(TWidget *target, QRect rect, QColor bg) {
|
||||
result.fill(bg);
|
||||
}
|
||||
|
||||
App::wnd()->widgetGrabbed().notify(true);
|
||||
|
||||
target->grabStart();
|
||||
target->render(&result, QPoint(0, 0), rect, QWidget::DrawChildren | QWidget::IgnoreMask);
|
||||
target->grabFinish();
|
||||
|
@ -92,9 +92,6 @@ public:
|
||||
base::Observable<void> &dragFinished() {
|
||||
return _dragFinished;
|
||||
}
|
||||
base::Observable<void> &widgetGrabbed() {
|
||||
return _widgetGrabbed;
|
||||
}
|
||||
|
||||
public slots:
|
||||
bool minimizeToTray();
|
||||
@ -184,8 +181,7 @@ private:
|
||||
base::Timer _inactivePressTimer;
|
||||
|
||||
base::Observable<void> _dragFinished;
|
||||
base::Observable<void> _widgetGrabbed;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace Window
|
||||
|
@ -26,12 +26,14 @@ namespace Window {
|
||||
|
||||
class Controller;
|
||||
class SectionWidget;
|
||||
enum class Column;
|
||||
|
||||
class SectionMemento {
|
||||
public:
|
||||
virtual object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
Column column,
|
||||
const QRect &geometry) = 0;
|
||||
|
||||
virtual object_ptr<LayerWidget> createLayer(
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "window/section_widget.h"
|
||||
|
||||
#include "application.h"
|
||||
#include "window/section_memento.h"
|
||||
#include <rpl/single.h>
|
||||
|
||||
namespace Window {
|
||||
@ -28,7 +29,7 @@ namespace Window {
|
||||
SectionWidget::SectionWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller)
|
||||
: AbstractSectionWidget(parent, controller) {
|
||||
: AbstractSectionWidget(parent, controller) {
|
||||
}
|
||||
|
||||
void SectionWidget::setGeometryWithTopMoved(
|
||||
@ -72,6 +73,10 @@ void SectionWidget::showAnimated(
|
||||
show();
|
||||
}
|
||||
|
||||
std::unique_ptr<SectionMemento> SectionWidget::createMemento() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SectionWidget::showFast() {
|
||||
show();
|
||||
showFinished();
|
||||
|
@ -45,10 +45,10 @@ public:
|
||||
}
|
||||
|
||||
// Float player interface.
|
||||
virtual bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) {
|
||||
virtual bool wheelEventFromFloatPlayer(QEvent *e) {
|
||||
return false;
|
||||
}
|
||||
virtual QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
virtual QRect rectForFloatPlayer() const {
|
||||
return mapToGlobal(rect());
|
||||
}
|
||||
|
||||
@ -67,7 +67,6 @@ class SectionMemento;
|
||||
struct SectionSlideParams {
|
||||
QPixmap oldContentCache;
|
||||
bool withTopBarShadow = false;
|
||||
bool withTabbedSection = false;
|
||||
|
||||
explicit operator bool() const {
|
||||
return !oldContentCache.isNull();
|
||||
@ -90,6 +89,9 @@ public:
|
||||
virtual bool hasTopBarShadow() const {
|
||||
return false;
|
||||
}
|
||||
virtual bool forceAnimateBack() const {
|
||||
return false;
|
||||
}
|
||||
void showAnimated(SlideDirection direction, const SectionSlideParams ¶ms);
|
||||
void showFast();
|
||||
|
||||
@ -109,7 +111,7 @@ public:
|
||||
|
||||
// Create a memento of that section to store it in the history stack.
|
||||
// This method may modify the section ("take" heavy items).
|
||||
virtual std::unique_ptr<SectionMemento> createMemento() = 0;
|
||||
virtual std::unique_ptr<SectionMemento> createMemento();
|
||||
|
||||
void setInnerFocus() {
|
||||
doSetInnerFocus();
|
||||
|
@ -23,9 +23,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "styles/style_window.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "shortcuts.h"
|
||||
#include "auth_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
@ -36,8 +38,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "observer_peer.h"
|
||||
|
||||
namespace Window {
|
||||
namespace {
|
||||
|
||||
TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller) : TWidget(parent)
|
||||
constexpr auto kThirdSectionInfoTimeoutMs = 1000;
|
||||
|
||||
} // namespace
|
||||
|
||||
TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller) : RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton)
|
||||
, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)
|
||||
@ -46,6 +53,7 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
|
||||
, _mediaType(this, langFactory(lng_media_type), st::topBarButton)
|
||||
, _call(this, st::topBarCall)
|
||||
, _search(this, st::topBarSearch)
|
||||
, _infoToggle(this, st::topBarInfo)
|
||||
, _menuToggle(this, st::topBarMenuToggle) {
|
||||
subscribe(Lang::Current().updated(), [this] { refreshLang(); });
|
||||
|
||||
@ -58,6 +66,7 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
|
||||
_call->setClickedCallback([this] { onCall(); });
|
||||
_search->setClickedCallback([this] { onSearch(); });
|
||||
_menuToggle->setClickedCallback([this] { showMenu(); });
|
||||
_infoToggle->setClickedCallback([this] { toggleInfoSection(); });
|
||||
|
||||
subscribe(_controller->searchInPeerChanged(), [this](PeerData *peer) {
|
||||
_searchInPeer = peer;
|
||||
@ -85,7 +94,12 @@ TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> contro
|
||||
updateControlsVisibility();
|
||||
}
|
||||
}));
|
||||
subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { updateControlsVisibility(); });
|
||||
subscribe(Global::RefPhoneCallsEnabledChanged(), [this] {
|
||||
updateControlsVisibility(); });
|
||||
|
||||
Auth().data().thirdSectionInfoEnabledValue()
|
||||
| rpl::on_next([this](bool) { updateInfoToggleActive(); })
|
||||
| rpl::start(lifetime());
|
||||
|
||||
setCursor(style::cur_pointer);
|
||||
updateControlsVisibility();
|
||||
@ -109,7 +123,9 @@ void TopBarWidget::onClearSelection() {
|
||||
|
||||
void TopBarWidget::onInfoClicked() {
|
||||
auto p = App::main() ? App::main()->historyPeer() : nullptr;
|
||||
if (p) Ui::showPeerProfile(p);
|
||||
if (p) {
|
||||
_controller->showPeerInfo(p);
|
||||
}
|
||||
}
|
||||
|
||||
void TopBarWidget::onSearch() {
|
||||
@ -163,6 +179,28 @@ void TopBarWidget::showMenu() {
|
||||
}
|
||||
}
|
||||
|
||||
void TopBarWidget::toggleInfoSection() {
|
||||
if (Adaptive::ThreeColumn()
|
||||
&& Auth().data().thirdSectionInfoEnabled()) {
|
||||
_controller->closeThirdSection();
|
||||
} else if (auto peer = App::main()->historyPeer()) {
|
||||
if (_controller->canShowThirdSection()) {
|
||||
Auth().data().setThirdSectionInfoEnabled(true);
|
||||
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
|
||||
if (Adaptive::ThreeColumn()) {
|
||||
_controller->showSection(Info::Memento(peer->id));
|
||||
} else {
|
||||
_controller->resizeForThirdSection();
|
||||
_controller->updateColumnLayout();
|
||||
}
|
||||
} else {
|
||||
_controller->showSection(Info::Memento(peer->id));
|
||||
}
|
||||
} else {
|
||||
updateControlsVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
|
||||
if (obj == _membersShowArea) {
|
||||
switch (e->type()) {
|
||||
@ -288,10 +326,14 @@ void TopBarWidget::updateControlsGeometry() {
|
||||
_menuToggle->moveToRight(right, otherButtonsTop);
|
||||
_mediaType->moveToRight(right, otherButtonsTop);
|
||||
if (_info->isHidden()) {
|
||||
right += _menuToggle->width();
|
||||
right += _menuToggle->width() + st::topBarSkip;
|
||||
} else {
|
||||
right += _info->width();
|
||||
}
|
||||
_infoToggle->moveToRight(right, otherButtonsTop);
|
||||
if (!_infoToggle->isHidden()) {
|
||||
right += _infoToggle->width() + st::topBarSkip;
|
||||
}
|
||||
_search->moveToRight(right, otherButtonsTop);
|
||||
right += _search->width() + st::topBarCallSkip;
|
||||
_call->moveToRight(right, otherButtonsTop);
|
||||
@ -322,6 +364,8 @@ void TopBarWidget::updateControlsVisibility() {
|
||||
_menuToggle->show();
|
||||
}
|
||||
_search->show();
|
||||
_infoToggle->setVisible(!Adaptive::OneColumn()
|
||||
&& _controller->canShowThirdSection());
|
||||
auto callsEnabled = false;
|
||||
if (auto user = historyPeer->asUser()) {
|
||||
callsEnabled = Global::PhoneCallsEnabled() && user->hasCalls();
|
||||
@ -421,6 +465,20 @@ void TopBarWidget::updateAdaptiveLayout() {
|
||||
rtlupdate(0, 0, st::titleUnreadCounterRight, st::titleUnreadCounterTop);
|
||||
});
|
||||
}
|
||||
updateInfoToggleActive();
|
||||
}
|
||||
|
||||
void TopBarWidget::updateInfoToggleActive() {
|
||||
auto infoThirdActive = Adaptive::ThreeColumn()
|
||||
&& Auth().data().thirdSectionInfoEnabled();
|
||||
auto iconOverride = infoThirdActive
|
||||
? &st::topBarInfoActive
|
||||
: nullptr;
|
||||
auto ripplOverride = infoThirdActive
|
||||
? &st::lightButtonBgOver
|
||||
: nullptr;
|
||||
_infoToggle->setIconOverride(iconOverride, iconOverride);
|
||||
_infoToggle->setRippleColorOverride(ripplOverride);
|
||||
}
|
||||
|
||||
Ui::RoundButton *TopBarWidget::mediaTypeButton() {
|
||||
|
@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/twidget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class PeerAvatarButton;
|
||||
@ -33,7 +33,7 @@ namespace Window {
|
||||
|
||||
class Controller;
|
||||
|
||||
class TopBarWidget : public TWidget, private base::Subscriber {
|
||||
class TopBarWidget : public Ui::RpWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -68,6 +68,7 @@ private:
|
||||
void refreshLang();
|
||||
void updateControlsGeometry();
|
||||
void selectedShowCallback();
|
||||
void updateInfoToggleActive();
|
||||
|
||||
void onForwardSelection();
|
||||
void onDeleteSelection();
|
||||
@ -76,6 +77,7 @@ private:
|
||||
void onCall();
|
||||
void onSearch();
|
||||
void showMenu();
|
||||
void toggleInfoSection();
|
||||
|
||||
void updateAdaptiveLayout();
|
||||
int countSelectedButtonsTop(float64 selectedShown);
|
||||
@ -97,6 +99,7 @@ private:
|
||||
|
||||
object_ptr<Ui::IconButton> _call;
|
||||
object_ptr<Ui::IconButton> _search;
|
||||
object_ptr<Ui::IconButton> _infoToggle;
|
||||
object_ptr<Ui::IconButton> _menuToggle;
|
||||
object_ptr<Ui::DropdownMenu> _menu = { nullptr };
|
||||
|
||||
|
@ -30,6 +30,10 @@ windowDefaultHeight: 600px;
|
||||
windowShadow: icon {{ "window_shadow", windowShadowFg }};
|
||||
windowShadowShift: 1px;
|
||||
|
||||
columnMinimalWidthLeft: 260px;
|
||||
columnMinimalWidthMain: 380px;
|
||||
columnMinimalWidthThird: 345px;
|
||||
|
||||
adaptiveChatWideWidth: 880px;
|
||||
|
||||
notifyBorder: windowShadowFgFallback;
|
||||
@ -257,9 +261,9 @@ topBarSearch: IconButton {
|
||||
width: 40px;
|
||||
height: topBarHeight;
|
||||
|
||||
icon: icon {{ "title_search-flip_horizontal", menuIconFg }};
|
||||
iconOver: icon {{ "title_search-flip_horizontal", menuIconFgOver }};
|
||||
iconPosition: point(11px, 19px);
|
||||
icon: icon {{ "top_bar_search", menuIconFg }};
|
||||
iconOver: icon {{ "top_bar_search", menuIconFgOver }};
|
||||
iconPosition: point(4px, 11px);
|
||||
|
||||
rippleAreaPosition: point(0px, 7px);
|
||||
rippleAreaSize: 40px;
|
||||
@ -268,10 +272,16 @@ topBarSearch: IconButton {
|
||||
}
|
||||
}
|
||||
topBarCall: IconButton(topBarSearch) {
|
||||
icon: icon {{ "add_contact_phone", menuIconFg }};
|
||||
iconOver: icon {{ "add_contact_phone", menuIconFgOver }};
|
||||
icon: icon {{ "top_bar_call", menuIconFg }};
|
||||
iconOver: icon {{ "top_bar_call", menuIconFgOver }};
|
||||
}
|
||||
topBarCallSkip: 4px;
|
||||
topBarInfo: IconButton(topBarSearch) {
|
||||
icon: icon {{ "top_bar_profile", menuIconFg }};
|
||||
iconOver: icon {{ "top_bar_profile", menuIconFgOver }};
|
||||
}
|
||||
topBarInfoActive: icon {{ "top_bar_profile", windowBgActive }};
|
||||
topBarSkip: -2px;
|
||||
topBarCallSkip: -1px;
|
||||
topBarMenuToggle: IconButton(topBarSearch) {
|
||||
width: 44px;
|
||||
|
||||
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "window/window_controller.h"
|
||||
|
||||
#include "window/main_window.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "styles/style_window.h"
|
||||
@ -30,6 +31,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace Window {
|
||||
namespace {
|
||||
|
||||
constexpr auto kThirdSectionInfoTimeoutMs = 1000;
|
||||
|
||||
} // namespace
|
||||
|
||||
void Controller::enableGifPauseReason(GifPauseReason reason) {
|
||||
if (!(_gifPauseReasons & reason)) {
|
||||
@ -61,21 +67,29 @@ int Controller::dialogsSmallColumnWidth() const {
|
||||
return st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x();
|
||||
}
|
||||
|
||||
int Controller::minimalThreeColumnWidth() const {
|
||||
return st::columnMinimalWidthLeft
|
||||
+ st::columnMinimalWidthMain
|
||||
+ st::columnMinimalWidthThird;
|
||||
}
|
||||
|
||||
Controller::ColumnLayout Controller::computeColumnLayout() const {
|
||||
auto layout = Adaptive::WindowLayout::OneColumn;
|
||||
|
||||
auto bodyWidth = window()->bodyWidget()->width();
|
||||
auto dialogsWidth = qRound(bodyWidth * dialogsWidthRatio().value());
|
||||
auto chatWidth = bodyWidth - dialogsWidth;
|
||||
accumulate_max(chatWidth, st::windowMinWidth);
|
||||
auto thirdWidth = 0;
|
||||
accumulate_max(chatWidth, st::columnMinimalWidthMain);
|
||||
dialogsWidth = bodyWidth - chatWidth;
|
||||
|
||||
auto useOneColumnLayout = [this, bodyWidth, dialogsWidth] {
|
||||
auto someSectionShown = !App::main()->selectingPeer() && App::main()->isSectionShown();
|
||||
if (dialogsWidth < st::dialogsPadding.x() && (Adaptive::OneColumn() || someSectionShown)) {
|
||||
if (dialogsWidth < st::dialogsPadding.x() && Adaptive::OneColumn()) {
|
||||
return true;
|
||||
}
|
||||
if (bodyWidth < st::windowMinWidth + st::dialogsWidthMin) {
|
||||
auto minimalNormal = st::columnMinimalWidthLeft
|
||||
+ st::columnMinimalWidthMain;
|
||||
if (bodyWidth < minimalNormal) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -89,6 +103,18 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
|
||||
return false;
|
||||
};
|
||||
|
||||
auto useNormalLayout = [this, bodyWidth] {
|
||||
// Used if useSmallColumnLayout() == false.
|
||||
if (bodyWidth < minimalThreeColumnWidth()) {
|
||||
return true;
|
||||
}
|
||||
if (!Auth().data().tabbedSelectorSectionEnabled()
|
||||
&& !Auth().data().thirdSectionInfoEnabled()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (useOneColumnLayout()) {
|
||||
dialogsWidth = chatWidth = bodyWidth;
|
||||
} else if (useSmallColumnLayout()) {
|
||||
@ -99,7 +125,7 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
|
||||
} else if (dialogsListFocused().value()) {
|
||||
return true;
|
||||
}
|
||||
return !App::main()->isSectionShown();
|
||||
return !App::main()->isMainSectionShown();
|
||||
};
|
||||
if (forceWideDialogs()) {
|
||||
dialogsWidth = st::dialogsWidthMin;
|
||||
@ -107,33 +133,81 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
|
||||
dialogsWidth = dialogsSmallColumnWidth();
|
||||
}
|
||||
chatWidth = bodyWidth - dialogsWidth;
|
||||
} else {
|
||||
} else if (useNormalLayout()) {
|
||||
layout = Adaptive::WindowLayout::Normal;
|
||||
accumulate_max(dialogsWidth, st::dialogsWidthMin);
|
||||
accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
|
||||
chatWidth = bodyWidth - dialogsWidth;
|
||||
} else {
|
||||
layout = Adaptive::WindowLayout::ThreeColumn;
|
||||
accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
|
||||
thirdWidth = st::columnMinimalWidthThird;
|
||||
accumulate_min(
|
||||
dialogsWidth,
|
||||
bodyWidth - thirdWidth - st::columnMinimalWidthMain);
|
||||
chatWidth = bodyWidth - dialogsWidth - thirdWidth;
|
||||
}
|
||||
return { bodyWidth, dialogsWidth, chatWidth, layout };
|
||||
return { bodyWidth, dialogsWidth, chatWidth, thirdWidth, layout };
|
||||
}
|
||||
|
||||
bool Controller::canProvideChatWidth(int requestedWidth) const {
|
||||
bool Controller::canShowThirdSection() const {
|
||||
auto currentLayout = computeColumnLayout();
|
||||
auto extendBy = requestedWidth - currentLayout.chatWidth;
|
||||
auto extendBy = minimalThreeColumnWidth()
|
||||
- currentLayout.bodyWidth;
|
||||
if (extendBy <= 0) {
|
||||
return true;
|
||||
}
|
||||
return window()->canExtendWidthBy(extendBy);
|
||||
}
|
||||
|
||||
void Controller::provideChatWidth(int requestedWidth) {
|
||||
auto currentLayout = computeColumnLayout();
|
||||
auto extendBy = requestedWidth - currentLayout.chatWidth;
|
||||
if (extendBy <= 0) {
|
||||
void Controller::resizeForThirdSection() {
|
||||
auto layout = computeColumnLayout();
|
||||
if (layout.windowLayout == Adaptive::WindowLayout::ThreeColumn) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto tabbedSelectorSectionEnabled =
|
||||
Auth().data().tabbedSelectorSectionEnabled();
|
||||
auto thirdSectionInfoEnabled =
|
||||
Auth().data().thirdSectionInfoEnabled();
|
||||
Auth().data().setTabbedSelectorSectionEnabled(false);
|
||||
Auth().data().setThirdSectionInfoEnabled(false);
|
||||
|
||||
auto extendBy = st::columnMinimalWidthThird;
|
||||
auto newBodyWidth = layout.bodyWidth + extendBy;
|
||||
dialogsWidthRatio().set(
|
||||
float64(layout.dialogsWidth) / newBodyWidth,
|
||||
true);
|
||||
window()->tryToExtendWidthBy(extendBy);
|
||||
auto newLayout = computeColumnLayout();
|
||||
if (newLayout.windowLayout != Adaptive::WindowLayout::OneColumn) {
|
||||
dialogsWidthRatio().set(float64(newLayout.bodyWidth - requestedWidth) / newLayout.bodyWidth, true);
|
||||
|
||||
Auth().data().setTabbedSelectorSectionEnabled(
|
||||
tabbedSelectorSectionEnabled);
|
||||
Auth().data().setThirdSectionInfoEnabled(
|
||||
thirdSectionInfoEnabled);
|
||||
}
|
||||
|
||||
void Controller::closeThirdSection() {
|
||||
auto newWindowSize = window()->size();
|
||||
auto layout = computeColumnLayout();
|
||||
if (layout.windowLayout == Adaptive::WindowLayout::ThreeColumn) {
|
||||
auto noResize = window()->isFullScreen()
|
||||
|| window()->isMaximized();
|
||||
auto newBodyWidth = noResize
|
||||
? layout.bodyWidth
|
||||
: (layout.bodyWidth - layout.thirdWidth);
|
||||
dialogsWidthRatio().set(
|
||||
float64(layout.dialogsWidth) / newBodyWidth,
|
||||
true);
|
||||
newWindowSize = QSize(
|
||||
window()->width() + (newBodyWidth - layout.bodyWidth),
|
||||
window()->height());
|
||||
}
|
||||
Auth().data().setTabbedSelectorSectionEnabled(false);
|
||||
Auth().data().setThirdSectionInfoEnabled(false);
|
||||
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
|
||||
if (window()->size() != newWindowSize) {
|
||||
window()->resize(newWindowSize);
|
||||
} else {
|
||||
updateColumnLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,15 +258,57 @@ void Controller::showJumpToDate(not_null<PeerData*> peer, QDate requestedDate) {
|
||||
Ui::show(std::move(box));
|
||||
}
|
||||
|
||||
void Controller::updateColumnLayout() {
|
||||
App::main()->updateColumnLayout();
|
||||
}
|
||||
|
||||
void Controller::showPeerHistory(
|
||||
PeerId peerId,
|
||||
Ui::ShowWay way,
|
||||
MsgId msgId) {
|
||||
Ui::showPeerHistory(peerId, msgId, way);
|
||||
}
|
||||
|
||||
void Controller::showPeerHistory(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ShowWay way,
|
||||
MsgId msgId) {
|
||||
Ui::showPeerHistory(peer, msgId, way);
|
||||
showPeerHistory(peer->id, way, msgId);
|
||||
}
|
||||
|
||||
void Controller::showWideSection(SectionMemento &&memento) {
|
||||
App::main()->showWideSection(std::move(memento));
|
||||
void Controller::showPeerHistory(
|
||||
not_null<History*> history,
|
||||
Ui::ShowWay way,
|
||||
MsgId msgId) {
|
||||
showPeerHistory(history->peer->id, way, msgId);
|
||||
}
|
||||
|
||||
void Controller::showPeerInfo(
|
||||
PeerId peerId,
|
||||
anim::type animated) {
|
||||
if (Adaptive::ThreeColumn()) {
|
||||
Auth().data().setThirdSectionInfoEnabled(true);
|
||||
Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs);
|
||||
}
|
||||
showSection(Info::Memento(peerId), animated);
|
||||
}
|
||||
|
||||
void Controller::showPeerInfo(
|
||||
not_null<PeerData*> peer,
|
||||
anim::type animated) {
|
||||
showPeerInfo(peer->id, animated);
|
||||
}
|
||||
|
||||
void Controller::showPeerInfo(
|
||||
not_null<History*> history,
|
||||
anim::type animated) {
|
||||
showPeerInfo(history->peer->id, animated);
|
||||
}
|
||||
|
||||
void Controller::showSection(
|
||||
SectionMemento &&memento,
|
||||
anim::type animated) {
|
||||
App::main()->showSection(std::move(memento), animated);
|
||||
}
|
||||
|
||||
void Controller::showBackFromStack() {
|
||||
|
@ -78,12 +78,47 @@ public:
|
||||
int bodyWidth;
|
||||
int dialogsWidth;
|
||||
int chatWidth;
|
||||
int thirdWidth;
|
||||
Adaptive::WindowLayout windowLayout;
|
||||
};
|
||||
ColumnLayout computeColumnLayout() const;
|
||||
int dialogsSmallColumnWidth() const;
|
||||
bool canProvideChatWidth(int requestedWidth) const;
|
||||
void provideChatWidth(int requestedWidth);
|
||||
void updateColumnLayout();
|
||||
bool canShowThirdSection() const;
|
||||
void resizeForThirdSection();
|
||||
void closeThirdSection();
|
||||
void showSection(
|
||||
SectionMemento &&memento,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showBackFromStack();
|
||||
void showSpecialLayer(
|
||||
object_ptr<LayerWidget> &&layer,
|
||||
LayerOptions options = LayerOption::Animated);
|
||||
void hideSpecialLayer(
|
||||
LayerOptions options = LayerOption::Animated);
|
||||
|
||||
void showPeerHistory(
|
||||
PeerId peerId,
|
||||
Ui::ShowWay way = Ui::ShowWay::ClearStack,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
void showPeerHistory(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ShowWay way = Ui::ShowWay::ClearStack,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
void showPeerHistory(
|
||||
not_null<History*> history,
|
||||
Ui::ShowWay way = Ui::ShowWay::ClearStack,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
|
||||
void showPeerInfo(
|
||||
PeerId peerId,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showPeerInfo(
|
||||
not_null<PeerData*> peer,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showPeerInfo(
|
||||
not_null<History*> history,
|
||||
anim::type animated = anim::type::normal);
|
||||
|
||||
void showJumpToDate(not_null<PeerData*> peer, QDate requestedDate);
|
||||
|
||||
@ -106,19 +141,8 @@ public:
|
||||
return _dialogsListDisplayForced;
|
||||
}
|
||||
|
||||
void showPeerHistory(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::ShowWay way = Ui::ShowWay::ClearStack,
|
||||
MsgId msgId = ShowAtUnreadMsgId);
|
||||
void showWideSection(SectionMemento &&memento);
|
||||
void showBackFromStack();
|
||||
void showSpecialLayer(
|
||||
object_ptr<LayerWidget> &&layer,
|
||||
LayerOptions options = LayerOption::Animated);
|
||||
void hideSpecialLayer(
|
||||
LayerOptions options = LayerOption::Animated);
|
||||
|
||||
private:
|
||||
int minimalThreeColumnWidth() const;
|
||||
not_null<MainWidget*> chats() const;
|
||||
|
||||
not_null<MainWindow*> _window;
|
||||
|
Loading…
Reference in New Issue
Block a user