mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Use rpl in some widgets and effects.
This commit is contained in:
parent
21d136e224
commit
c302219f9e
120 changed files with 2119 additions and 671 deletions
|
@ -78,6 +78,8 @@ slideDuration: 240;
|
|||
slideShift: 100px;
|
||||
slideShadow: icon {{ "slide_shadow", slideFadeOutShadowFg }};
|
||||
|
||||
slideWrapDuration: 150;
|
||||
|
||||
linkCropLimit: 360px;
|
||||
linkFont: normalFont;
|
||||
linkOverFont: font(fsize underline);
|
||||
|
|
|
@ -365,9 +365,14 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline Return operator()(Args... args) {
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename = std::enable_if_t<(sizeof...(Args) == sizeof...(OtherArgs))>>
|
||||
inline Return operator()(OtherArgs&&... args) {
|
||||
Assert(data_.vtable != nullptr);
|
||||
return data_.vtable->call(data_.storage, std::forward<Args>(args)...);
|
||||
return data_.vtable->call(
|
||||
data_.storage,
|
||||
std::forward<OtherArgs>(args)...);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
|
@ -437,9 +442,14 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline Return operator()(Args... args) const {
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename = std::enable_if_t<(sizeof...(Args) == sizeof...(OtherArgs))>>
|
||||
inline Return operator()(OtherArgs&&... args) const {
|
||||
Assert(this->data_.vtable != nullptr);
|
||||
return this->data_.vtable->const_call(this->data_.storage, std::forward<Args>(args)...);
|
||||
return this->data_.vtable->const_call(
|
||||
this->data_.storage,
|
||||
std::forward<OtherArgs>(args)...);
|
||||
}
|
||||
|
||||
void swap(lambda &other) {
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <rpl/producer.h>
|
||||
#include "base/type_traits.h"
|
||||
|
||||
namespace base {
|
||||
|
@ -460,4 +461,31 @@ private:
|
|||
|
||||
void HandleObservables();
|
||||
|
||||
template <
|
||||
typename Type,
|
||||
typename = std::enable_if_t<!std::is_same_v<Type, void>>>
|
||||
inline rpl::producer<Type> ObservableViewer(
|
||||
base::Observable<Type> &observable) {
|
||||
return [&observable](const rpl::consumer<Type> &consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
lifetime.make_state<base::Subscription>(
|
||||
observable.add_subscription([consumer](auto &&update) {
|
||||
consumer.put_next_copy(update);
|
||||
}));
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
inline rpl::producer<> ObservableViewer(
|
||||
base::Observable<void> &observable) {
|
||||
return [&observable](const rpl::consumer<> &consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
lifetime.make_state<base::Subscription>(
|
||||
observable.add_subscription([consumer]() {
|
||||
consumer.put_next({});
|
||||
}));
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gsl/gsl_assert>
|
||||
#include "base/variant.h"
|
||||
|
||||
namespace base {
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "layerwidget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
|
||||
namespace Ui {
|
||||
|
@ -58,7 +59,7 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class BoxContent : public TWidget, protected base::Subscriber {
|
||||
class BoxContent : public Ui::RpWidget, protected base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
|
|
@ -24,7 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
|
@ -252,7 +252,7 @@ std::vector<not_null<UserData*>> &EditPrivacyBox::exceptionUsers(Exception excep
|
|||
Unexpected("Invalid exception value.");
|
||||
}
|
||||
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> &EditPrivacyBox::exceptionLink(Exception exception) {
|
||||
object_ptr<Ui::SlideWrap<Ui::LinkButton>> &EditPrivacyBox::exceptionLink(Exception exception) {
|
||||
switch (exception) {
|
||||
case Exception::Always: return _alwaysLink;
|
||||
case Exception::Never: return _neverLink;
|
||||
|
@ -284,9 +284,10 @@ void EditPrivacyBox::createWidgets() {
|
|||
widget.create(this, text, Ui::FlatLabel::InitType::Simple, st);
|
||||
};
|
||||
auto createExceptionLink = [this](Exception exception) {
|
||||
exceptionLink(exception).create(this, object_ptr<Ui::LinkButton>(this, exceptionLinkText(exception)), exceptionLinkMargins(), [this] {
|
||||
resizeGetHeight(width());
|
||||
});
|
||||
exceptionLink(exception).create(this, object_ptr<Ui::LinkButton>(this, exceptionLinkText(exception)), exceptionLinkMargins());
|
||||
exceptionLink(exception)->heightValue()
|
||||
| rpl::on_next([this](int) { resizeToWidth(width()); })
|
||||
| rpl::start(lifetime());
|
||||
exceptionLink(exception)->entity()->setClickedCallback([this, exception] { editExceptionUsers(exception); });
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class RadioenumGroup;
|
|||
template <typename Enum>
|
||||
class Radioenum;
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap;
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
||||
class EditPrivacyBox : public BoxContent, private MTP::Sender {
|
||||
|
@ -103,7 +103,7 @@ private:
|
|||
void editExceptionUsers(Exception exception);
|
||||
QString exceptionLinkText(Exception exception);
|
||||
std::vector<not_null<UserData*>> &exceptionUsers(Exception exception);
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> &exceptionLink(Exception exception);
|
||||
object_ptr<Ui::SlideWrap<Ui::LinkButton>> &exceptionLink(Exception exception);
|
||||
|
||||
std::unique_ptr<Controller> _controller;
|
||||
Option _option = Option::Everyone;
|
||||
|
@ -116,8 +116,8 @@ private:
|
|||
object_ptr<Ui::Radioenum<Option>> _nobody = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _warning = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _exceptionsTitle = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _alwaysLink = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _neverLink = { nullptr };
|
||||
object_ptr<Ui::SlideWrap<Ui::LinkButton>> _alwaysLink = { nullptr };
|
||||
object_ptr<Ui::SlideWrap<Ui::LinkButton>> _neverLink = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _exceptionsDescription = { nullptr };
|
||||
|
||||
std::vector<not_null<UserData*>> _alwaysUsers;
|
||||
|
|
|
@ -127,7 +127,9 @@ void NotificationsBox::prepare() {
|
|||
_sampleOpacities.push_back(Animation());
|
||||
}
|
||||
_countSlider->setActiveSectionFast(_oldCount - 1);
|
||||
_countSlider->setSectionActivatedCallback([this] { countChanged(); });
|
||||
_countSlider->sectionActivated()
|
||||
| rpl::on_next([this](int) { countChanged(); })
|
||||
| rpl::start(lifetime());
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "observer_peer.h"
|
||||
#include "storage/file_download.h"
|
||||
|
@ -44,9 +44,10 @@ void PeerListBox::createMultiSelect() {
|
|||
Expects(_select == nullptr);
|
||||
|
||||
auto entity = object_ptr<Ui::MultiSelect>(this, st::contactsMultiSelect, langFactory(lng_participant_filter));
|
||||
auto margins = style::margins(0, 0, 0, 0);
|
||||
auto callback = [this] { updateScrollSkips(); };
|
||||
_select.create(this, std::move(entity), margins, std::move(callback));
|
||||
_select.create(this, std::move(entity));
|
||||
_select->heightValue()
|
||||
| rpl::on_next([this](int) { updateScrollSkips(); })
|
||||
| rpl::start(lifetime());
|
||||
_select->entity()->setSubmittedCallback([this](bool chtrlShiftEnter) { _inner->submitted(); });
|
||||
_select->entity()->setQueryChangedCallback([this](const QString &query) { searchQueryChanged(query); });
|
||||
_select->entity()->setItemRemovedCallback([this](uint64 itemId) {
|
||||
|
@ -86,7 +87,7 @@ void PeerListBox::prepare() {
|
|||
|
||||
setDimensions(st::boxWideWidth, st::boxMaxListHeight);
|
||||
if (_select) {
|
||||
_select->finishAnimation();
|
||||
_select->finishAnimations();
|
||||
_scrollBottomFixed = true;
|
||||
onScrollToY(0);
|
||||
}
|
||||
|
@ -1158,7 +1159,9 @@ void PeerListBox::Inner::submitted() {
|
|||
}
|
||||
}
|
||||
|
||||
void PeerListBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void PeerListBox::Inner::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
loadProfilePhotos();
|
||||
|
|
|
@ -29,7 +29,7 @@ class RippleAnimation;
|
|||
class RoundImageCheckbox;
|
||||
class MultiSelect;
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap;
|
||||
class SlideWrap;
|
||||
class FlatLabel;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -378,7 +378,7 @@ private:
|
|||
void updateScrollSkips();
|
||||
void searchQueryChanged(const QString &query);
|
||||
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::MultiSelect>> _select = { nullptr };
|
||||
object_ptr<Ui::SlideWrap<Ui::MultiSelect>> _select = { nullptr };
|
||||
|
||||
class Inner;
|
||||
QPointer<Inner> _inner;
|
||||
|
@ -401,8 +401,6 @@ public:
|
|||
|
||||
void clearSelection();
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
void searchQueryChanged(QString query);
|
||||
void submitted();
|
||||
|
||||
|
@ -441,10 +439,11 @@ public:
|
|||
signals:
|
||||
void mustScrollTo(int ymin, int ymax);
|
||||
|
||||
public slots:
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void enterEventHook(QEvent *e) override;
|
||||
|
|
|
@ -311,7 +311,9 @@ void ShareBox::Inner::invalidateCache() {
|
|||
}
|
||||
}
|
||||
|
||||
void ShareBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void ShareBox::Inner::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
loadProfilePhotos(visibleTop);
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,6 @@ public:
|
|||
void activateSkipRow(int direction);
|
||||
void activateSkipColumn(int direction);
|
||||
void activateSkipPage(int pageHeight, int direction);
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
void updateFilter(QString filter = QString());
|
||||
|
||||
~Inner();
|
||||
|
@ -138,6 +137,10 @@ signals:
|
|||
void searchByUsername();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void enterEventHook(QEvent *e) override;
|
||||
void leaveEventHook(QEvent *e) override;
|
||||
|
|
|
@ -401,11 +401,6 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
}
|
||||
|
||||
bool StickerSetBox::Inner::loaded() const {
|
||||
return _loaded && !_pack.isEmpty();
|
||||
}
|
||||
|
|
|
@ -73,7 +73,6 @@ public:
|
|||
base::lambda<TextWithEntities()> title() const;
|
||||
QString shortName() const;
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
void install();
|
||||
|
||||
~Inner();
|
||||
|
@ -119,8 +118,6 @@ private:
|
|||
int32 _setHash = 0;
|
||||
MTPDstickerSet::Flags _setFlags = 0;
|
||||
|
||||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
MTPInputStickerSet _input;
|
||||
|
||||
mtpRequestId _installRequest = 0;
|
||||
|
|
|
@ -243,9 +243,9 @@ void StickersBox::prepare() {
|
|||
preloadArchivedSets();
|
||||
}
|
||||
setNoContentMargin(true);
|
||||
_tabs->setSectionActivatedCallback([this] {
|
||||
switchTab();
|
||||
});
|
||||
_tabs->sectionActivated()
|
||||
| rpl::on_next([this](int) { switchTab(); })
|
||||
| rpl::start(lifetime());
|
||||
refreshTabs();
|
||||
}
|
||||
if (_installed.widget() && _section != Section::Installed) _installed.widget()->hide();
|
||||
|
@ -1532,7 +1532,9 @@ void StickersBox::Inner::setRemovedSets(const Stickers::Order &removed) {
|
|||
}
|
||||
}
|
||||
|
||||
void StickersBox::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void StickersBox::Inner::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
updateScrollbarWidth();
|
||||
|
|
|
@ -173,7 +173,6 @@ public:
|
|||
_loadMoreCallback = std::move(callback);
|
||||
}
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
void setMinHeight(int newWidth, int minHeight);
|
||||
|
||||
int getVisibleTop() const {
|
||||
|
@ -183,6 +182,10 @@ public:
|
|||
~Inner();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -75,7 +75,10 @@ void DebugInfoBox::updateText() {
|
|||
|
||||
} // namespace
|
||||
|
||||
TopBar::TopBar(QWidget *parent, const base::weak_unique_ptr<Call> &call) : TWidget(parent)
|
||||
TopBar::TopBar(
|
||||
QWidget *parent,
|
||||
const base::weak_unique_ptr<Call> &call)
|
||||
: RpWidget(parent)
|
||||
, _call(call)
|
||||
, _durationLabel(this, st::callBarLabel)
|
||||
, _fullInfoLabel(this, st::callBarInfoLabel)
|
||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "base/weak_unique_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
|
@ -34,7 +35,7 @@ namespace Calls {
|
|||
|
||||
class Call;
|
||||
|
||||
class TopBar : public TWidget, private base::Subscriber {
|
||||
class TopBar : public Ui::RpWidget, private base::Subscriber {
|
||||
public:
|
||||
TopBar(QWidget *parent, const base::weak_unique_ptr<Call> &call);
|
||||
|
||||
|
|
|
@ -323,8 +323,10 @@ EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*>
|
|||
connect(_picker, SIGNAL(hidden()), this, SLOT(onPickerHidden()));
|
||||
}
|
||||
|
||||
void EmojiListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
Inner::setVisibleTopBottom(visibleTop, visibleBottom);
|
||||
void EmojiListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
|
||||
if (_footer) {
|
||||
_footer->setCurrentSectionIcon(currentSection(visibleTop));
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ public:
|
|||
|
||||
using Section = Ui::Emoji::Section;
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
void refreshRecent() override;
|
||||
void clearSelection() override;
|
||||
object_ptr<TabbedSelector::InnerFooter> createFooter() override;
|
||||
|
@ -112,6 +111,10 @@ signals:
|
|||
void switchToStickers();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
@ -136,6 +139,7 @@ private:
|
|||
int rowsTop = 0;
|
||||
int rowsBottom = 0;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
bool enumerateSections(Callback callback) const;
|
||||
SectionInfo sectionInfo(int section) const;
|
||||
|
|
|
@ -156,9 +156,11 @@ object_ptr<TabbedSelector::InnerFooter> GifsListWidget::createFooter() {
|
|||
return std::move(result);
|
||||
}
|
||||
|
||||
void GifsListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void GifsListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
auto top = getVisibleTop();
|
||||
Inner::setVisibleTopBottom(visibleTop, visibleBottom);
|
||||
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
|
||||
if (top != getVisibleTop()) {
|
||||
_lastScrolled = getms();
|
||||
}
|
||||
|
|
|
@ -51,8 +51,6 @@ public:
|
|||
void clearSelection() override;
|
||||
object_ptr<TabbedSelector::InnerFooter> createFooter() override;
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) override;
|
||||
void inlineItemRepaint(const InlineBots::Layout::ItemBase *layout) override;
|
||||
bool inlineItemVisible(const InlineBots::Layout::ItemBase *layout) override;
|
||||
|
@ -69,6 +67,10 @@ public:
|
|||
~GifsListWidget();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -468,9 +468,11 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
|
|||
return std::move(result);
|
||||
}
|
||||
|
||||
void StickersListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void StickersListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
auto top = getVisibleTop();
|
||||
Inner::setVisibleTopBottom(visibleTop, visibleBottom);
|
||||
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
|
||||
if (_section == Section::Featured) {
|
||||
readVisibleSets();
|
||||
}
|
||||
|
|
|
@ -54,8 +54,6 @@ public:
|
|||
void fillIcons(QList<StickerIcon> &icons);
|
||||
bool preventAutoHide();
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
uint64 currentSet(int yOffset) const;
|
||||
|
||||
void installedLocally(uint64 setId);
|
||||
|
@ -65,6 +63,10 @@ public:
|
|||
~StickersListWidget();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -77,7 +77,7 @@ bool TabbedSection::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn
|
|||
return _selector->wheelEventFromFloatPlayer(e);
|
||||
}
|
||||
|
||||
QRect TabbedSection::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect TabbedSection::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return _selector->rectForFloatPlayer();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
|
@ -285,7 +285,7 @@ void TabbedSelector::Tab::saveScrollTop() {
|
|||
_scrollTop = widget()->getVisibleTop();
|
||||
}
|
||||
|
||||
TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> controller) : TWidget(parent)
|
||||
TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> controller) : RpWidget(parent)
|
||||
, _tabsSlider(this, st::emojiTabs)
|
||||
, _topShadow(this, st::shadowFg)
|
||||
, _bottomShadow(this, st::shadowFg)
|
||||
|
@ -472,7 +472,7 @@ bool TabbedSelector::wheelEventFromFloatPlayer(QEvent *e) {
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect TabbedSelector::rectForFloatPlayer() {
|
||||
QRect TabbedSelector::rectForFloatPlayer() const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
@ -602,9 +602,9 @@ void TabbedSelector::createTabsSlider() {
|
|||
_tabsSlider->setSections(sections);
|
||||
|
||||
_tabsSlider->setActiveSectionFast(static_cast<int>(_currentTabType));
|
||||
_tabsSlider->setSectionActivatedCallback([this] {
|
||||
switchTab();
|
||||
});
|
||||
_tabsSlider->sectionActivated()
|
||||
| rpl::on_next([this](int) { switchTab(); })
|
||||
| rpl::start(lifetime());
|
||||
|
||||
_tabsSlider->resizeToWidth(width());
|
||||
_tabsSlider->moveToLeft(0, 0);
|
||||
|
@ -701,7 +701,7 @@ TabbedSelector::Inner::Inner(QWidget *parent, not_null<Window::Controller*> cont
|
|||
, _controller(controller) {
|
||||
}
|
||||
|
||||
void TabbedSelector::Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void TabbedSelector::Inner::visibleTopBottomUpdated(int visibleTop, int visibleBottom) {
|
||||
auto oldVisibleHeight = getVisibleBottom() - getVisibleTop();
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
|
|
@ -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 "ui/effects/panel_animation.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "auth_session.h"
|
||||
|
@ -52,7 +52,7 @@ class EmojiListWidget;
|
|||
class StickersListWidget;
|
||||
class GifsListWidget;
|
||||
|
||||
class TabbedSelector : public TWidget, private base::Subscriber {
|
||||
class TabbedSelector : public Ui::RpWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e);
|
||||
QRect rectForFloatPlayer();
|
||||
QRect rectForFloatPlayer() const;
|
||||
|
||||
~TabbedSelector();
|
||||
|
||||
|
@ -207,8 +207,6 @@ class TabbedSelector::Inner : public TWidget {
|
|||
public:
|
||||
Inner(QWidget *parent, not_null<Window::Controller*> controller);
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
int getVisibleTop() const {
|
||||
return _visibleTop;
|
||||
}
|
||||
|
@ -235,6 +233,10 @@ signals:
|
|||
void disableScroll(bool disabled);
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
not_null<Window::Controller*> controller() const {
|
||||
return _controller;
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ constexpr auto kTagsCount = " << langpack_.tags.size() << ";\n\
|
|||
}
|
||||
header_->stream() << "\
|
||||
\n\
|
||||
enum LangKey {\n";
|
||||
enum LangKey : int {\n";
|
||||
for (auto &entry : langpack_.entries) {
|
||||
header_->stream() << "\t" << getFullKey(entry) << ",\n";
|
||||
}
|
||||
|
|
|
@ -1423,7 +1423,9 @@ PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void DialogsInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void DialogsInner::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
loadPeerPhotos();
|
||||
|
|
|
@ -107,7 +107,6 @@ public:
|
|||
void setLoadMoreCallback(base::lambda<void()> callback) {
|
||||
_loadMoreCallback = std::move(callback);
|
||||
}
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
base::Observable<UserData*> searchFromUserChanged;
|
||||
|
||||
|
@ -133,6 +132,10 @@ signals:
|
|||
void refreshHashtags();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -271,7 +271,7 @@ bool DialogsWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect DialogsWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect DialogsWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||
void notify_historyMuteUpdated(History *history);
|
||||
|
|
|
@ -18,6 +18,8 @@ to link the code of portions of this program with the OpenSSL library.
|
|||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "facades.h"
|
||||
|
||||
#include "profile/profile_section_memento.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "media/media_clip_reader.h"
|
||||
|
|
|
@ -233,7 +233,9 @@ InnerWidget::InnerWidget(QWidget *parent, not_null<Window::Controller*> controll
|
|||
requestAdmins();
|
||||
}
|
||||
|
||||
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
auto scrolledUp = (visibleTop < _visibleTop);
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
|
|
@ -50,9 +50,6 @@ public:
|
|||
return _channel;
|
||||
}
|
||||
|
||||
// Updates the area that is visible inside the scroll container.
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
// Set the correct scroll position after being resized.
|
||||
void restoreScrollPosition();
|
||||
|
||||
|
@ -76,6 +73,10 @@ public:
|
|||
~InnerWidget();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -431,7 +431,7 @@ bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Windo
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
void applyFilter(FilterValue &&value);
|
||||
|
||||
|
|
|
@ -3515,7 +3515,7 @@ bool HistoryWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect HistoryWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
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);
|
||||
|
|
|
@ -348,7 +348,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
void app_sendBotCallback(const HistoryMessageReplyMarkup::Button *button, not_null<const HistoryItem*> msg, int row, int col);
|
||||
|
||||
|
|
|
@ -80,7 +80,9 @@ Inner::Inner(QWidget *parent, not_null<Window::Controller*> controller) : TWidge
|
|||
}));
|
||||
}
|
||||
|
||||
void Inner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void Inner::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
_visibleBottom = visibleBottom;
|
||||
if (_visibleTop != visibleTop) {
|
||||
_visibleTop = visibleTop;
|
||||
|
|
|
@ -74,7 +74,6 @@ public:
|
|||
void hideInlineRowsPanel();
|
||||
void clearInlineRowsPanel();
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
void preloadImages();
|
||||
|
||||
void inlineItemLayoutChanged(const ItemBase *layout) override;
|
||||
|
@ -90,6 +89,10 @@ public:
|
|||
~Inner();
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -499,4 +499,14 @@ Instance &Current() {
|
|||
return Messenger::Instance().langpack();
|
||||
}
|
||||
|
||||
rpl::producer<QString> Viewer(LangKey key) {
|
||||
return
|
||||
rpl::single(Current().getValue(key))
|
||||
| then(
|
||||
base::ObservableViewer(Current().updated())
|
||||
| rpl::map([=](auto&&) {
|
||||
return Current().getValue(key);
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace Lang
|
||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/producer.h>
|
||||
#include "lang_auto.h"
|
||||
#include "base/weak_unique_ptr.h"
|
||||
|
||||
|
@ -48,6 +49,8 @@ QString DefaultLanguageId();
|
|||
class Instance;
|
||||
Instance &Current();
|
||||
|
||||
rpl::producer<QString> Viewer(LangKey key);
|
||||
|
||||
class Instance {
|
||||
public:
|
||||
Instance() {
|
||||
|
@ -84,15 +87,20 @@ public:
|
|||
return _updated;
|
||||
}
|
||||
|
||||
QString getValue(LangKey key) {
|
||||
QString getValue(LangKey key) const {
|
||||
Expects(key >= 0 && key < kLangKeysCount);
|
||||
Expects(_values.size() == kLangKeysCount);
|
||||
return _values[key];
|
||||
}
|
||||
bool isNonDefaultPlural(LangKey key) {
|
||||
bool isNonDefaultPlural(LangKey key) const {
|
||||
Expects(key >= 0 && key < kLangKeysCount);
|
||||
Expects(_nonDefaultSet.size() == kLangKeysCount);
|
||||
return _nonDefaultSet[key] || _nonDefaultSet[key + 1] || _nonDefaultSet[key + 2] || _nonDefaultSet[key + 3] || _nonDefaultSet[key + 4] || _nonDefaultSet[key + 5];
|
||||
return _nonDefaultSet[key]
|
||||
|| _nonDefaultSet[key + 1]
|
||||
|| _nonDefaultSet[key + 2]
|
||||
|| _nonDefaultSet[key + 3]
|
||||
|| _nonDefaultSet[key + 4]
|
||||
|| _nonDefaultSet[key + 5];
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -388,6 +388,7 @@ void LayerStackWidget::setCacheImages() {
|
|||
auto bodyCache = QPixmap(), mainMenuCache = QPixmap();
|
||||
auto specialLayerCache = QPixmap();
|
||||
if (_specialLayer) {
|
||||
myEnsureResized(_specialLayer);
|
||||
auto sides = RectPart::Left | RectPart::Right;
|
||||
if (_specialLayer->y() > 0) {
|
||||
sides |= RectPart::Top;
|
||||
|
@ -673,6 +674,7 @@ void LayerStackWidget::initChildLayer(LayerWidget *layer) {
|
|||
layer->setClosedCallback([this, layer] { onLayerClosed(layer); });
|
||||
layer->setResizedCallback([this] { onLayerResized(); });
|
||||
connect(layer, SIGNAL(destroyed(QObject*)), this, SLOT(onLayerDestroyed(QObject*)));
|
||||
myEnsureResized(layer);
|
||||
layer->parentResized();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,16 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Window {
|
||||
class MainMenu;
|
||||
class Controller;
|
||||
} // namespace Window
|
||||
|
||||
class LayerWidget : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
class LayerWidget : public Ui::RpWidget {
|
||||
public:
|
||||
using TWidget::TWidget;
|
||||
using RpWidget::RpWidget;
|
||||
|
||||
virtual void parentResized() = 0;
|
||||
virtual void showFinished() {
|
||||
|
|
|
@ -119,7 +119,10 @@ MainWidget::Float::Float(QWidget *parent, HistoryItem *item, ToggleCallback togg
|
|||
}) {
|
||||
}
|
||||
|
||||
MainWidget::MainWidget(QWidget *parent, not_null<Window::Controller*> controller) : TWidget(parent)
|
||||
MainWidget::MainWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _dialogsWidth(st::dialogsWidthMin)
|
||||
, _sideShadow(this, st::shadowFg)
|
||||
|
@ -1813,7 +1816,10 @@ void MainWidget::createPlayer() {
|
|||
return;
|
||||
}
|
||||
if (!_player) {
|
||||
_player.create(this, [this] { playerHeightUpdated(); });
|
||||
_player.create(this);
|
||||
_player->heightValue()
|
||||
| rpl::on_next([this](int) { playerHeightUpdated(); })
|
||||
| rpl::start(lifetime());
|
||||
_player->entity()->setCloseCallback([this] { closeBothPlayers(); });
|
||||
_playerVolume.create(this);
|
||||
_player->entity()->volumeWidgetCreated(_playerVolume);
|
||||
|
@ -1870,7 +1876,12 @@ void MainWidget::setCurrentCall(Calls::Call *call) {
|
|||
|
||||
void MainWidget::createCallTopBar() {
|
||||
Expects(_currentCall != nullptr);
|
||||
_callTopBar.create(this, object_ptr<Calls::TopBar>(this, _currentCall), style::margins(0, 0, 0, 0), [this] { callTopBarHeightUpdated(); });
|
||||
_callTopBar.create(this, object_ptr<Calls::TopBar>(this, _currentCall));
|
||||
_callTopBar->heightValue()
|
||||
| rpl::on_next([this](int value) {
|
||||
callTopBarHeightUpdated(value);
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
orderWidgets();
|
||||
if (_a_show.animating()) {
|
||||
_callTopBar->showFast();
|
||||
|
@ -1889,8 +1900,7 @@ void MainWidget::destroyCallTopBar() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWidget::callTopBarHeightUpdated() {
|
||||
auto callTopBarHeight = _callTopBar ? _callTopBar->height() : 0;
|
||||
void MainWidget::callTopBarHeightUpdated(int callTopBarHeight) {
|
||||
if (!callTopBarHeight && !_currentCall) {
|
||||
_callTopBar.destroyDelayed();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "history/history_common.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "base/weak_unique_ptr.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Notify {
|
||||
struct PeerUpdate;
|
||||
|
@ -46,7 +47,7 @@ namespace Ui {
|
|||
class PlainShadow;
|
||||
class DropdownMenu;
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap;
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -149,7 +150,7 @@ class ItemBase;
|
|||
} // namespace Layout
|
||||
} // namespace InlineBots
|
||||
|
||||
class MainWidget : public TWidget, public RPCSender, private base::Subscriber {
|
||||
class MainWidget : public Ui::RpWidget, public RPCSender, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -506,7 +507,7 @@ private:
|
|||
void setCurrentCall(Calls::Call *call);
|
||||
void createCallTopBar();
|
||||
void destroyCallTopBar();
|
||||
void callTopBarHeightUpdated();
|
||||
void callTopBarHeightUpdated(int callTopBarHeight);
|
||||
|
||||
void sendReadRequest(PeerData *peer, MsgId upTo);
|
||||
void channelReadDone(PeerData *peer, const MTPBool &result);
|
||||
|
@ -620,7 +621,7 @@ private:
|
|||
object_ptr<OverviewWidget> _overview = { nullptr };
|
||||
|
||||
base::weak_unique_ptr<Calls::Call> _currentCall;
|
||||
object_ptr<Ui::WidgetSlideWrap<Calls::TopBar>> _callTopBar = { nullptr };
|
||||
object_ptr<Ui::SlideWrap<Calls::TopBar>> _callTopBar = { nullptr };
|
||||
|
||||
object_ptr<Window::PlayerWrapWidget> _player = { nullptr };
|
||||
object_ptr<Media::Player::VolumeWidget> _playerVolume = { nullptr };
|
||||
|
|
|
@ -84,7 +84,7 @@ QPoint Widget::PlayButton::prepareRippleStartPosition() const {
|
|||
return QPoint(mapFromGlobal(QCursor::pos()) - st::mediaPlayerButton.rippleAreaPosition);
|
||||
}
|
||||
|
||||
Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||
Widget::Widget(QWidget *parent) : RpWidget(parent)
|
||||
, _nameLabel(this, st::mediaPlayerName)
|
||||
, _timeLabel(this, st::mediaPlayerTime)
|
||||
, _playPause(this)
|
||||
|
|
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class AudioMsgId;
|
||||
|
||||
namespace Ui {
|
||||
|
@ -41,7 +43,7 @@ class PlayButton;
|
|||
class VolumeWidget;
|
||||
struct TrackState;
|
||||
|
||||
class Widget : public TWidget, private base::Subscriber {
|
||||
class Widget : public Ui::RpWidget, private base::Subscriber {
|
||||
public:
|
||||
Widget(QWidget *parent);
|
||||
|
||||
|
|
|
@ -2149,7 +2149,7 @@ bool OverviewWidget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColum
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect OverviewWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect OverviewWidget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -350,7 +350,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
void ui_repaintHistoryItem(not_null<const HistoryItem*> item);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "styles/style_profile.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "mainwidget.h"
|
||||
#include "observer_peer.h"
|
||||
|
|
|
@ -50,7 +50,7 @@ int PeerListWidget::resizeGetHeight(int newWidth) {
|
|||
return newHeight + _st.bottom;
|
||||
}
|
||||
|
||||
void PeerListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void PeerListWidget::visibleTopBottomUpdated(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@ class PeerListWidget : public BlockWidget {
|
|||
public:
|
||||
PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const style::ProfilePeerListItem &st = st::profileMemberItem, const QString &removeText = QString());
|
||||
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
struct Item {
|
||||
explicit Item(PeerData *peer);
|
||||
~Item();
|
||||
|
@ -100,12 +98,14 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintOutlinedRect(Painter &p, int x, int y, int w, int h) const;
|
||||
void refreshVisibility();
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
void paintContents(Painter &p) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
|
|
@ -105,7 +105,9 @@ InnerWidget::InnerWidget(QWidget *parent, not_null<UserData*> user) : TWidget(pa
|
|||
_contentTop = st::profileCommonGroupsSkip;
|
||||
}
|
||||
|
||||
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
|
@ -449,7 +451,7 @@ bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Windo
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -102,9 +102,6 @@ public:
|
|||
return _user;
|
||||
}
|
||||
|
||||
// Updates the area that is visible inside the scroll container.
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
void resizeToWidth(int newWidth, int minHeight) {
|
||||
_minHeight = minHeight;
|
||||
return TWidget::resizeToWidth(newWidth);
|
||||
|
@ -119,15 +116,17 @@ signals:
|
|||
void cancelled();
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void updateSelected(QPoint localPos);
|
||||
void updateRow(int index);
|
||||
|
@ -191,7 +190,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
|
@ -70,7 +70,7 @@ void InnerWidget::createBlocks() {
|
|||
}
|
||||
}
|
||||
|
||||
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void InnerWidget::visibleTopBottomUpdated(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
|
|
|
@ -41,9 +41,6 @@ public:
|
|||
return TWidget::resizeToWidth(newWidth);
|
||||
}
|
||||
|
||||
// Updates the area that is visible inside the scroll container.
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
// Profile fixed top bar should use this flag to decide
|
||||
// if it shows "Share contact" button or not.
|
||||
// It should show it only if it is hidden in the cover.
|
||||
|
@ -61,12 +58,14 @@ private slots:
|
|||
void onBlockHeightUpdated();
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void createBlocks();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Profile {
|
||||
|
||||
UserpicButton::UserpicButton(QWidget *parent, PeerData *peer, int size) : AbstractButton(parent)
|
||||
UserpicButton::UserpicButton(QWidget *parent, not_null<PeerData*> peer, int size) : AbstractButton(parent)
|
||||
, _size(size ? size : st::profilePhotoSize)
|
||||
, _peer(peer) {
|
||||
resize(_size, _size);
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Profile {
|
|||
|
||||
class UserpicButton : public Ui::AbstractButton, private base::Subscriber {
|
||||
public:
|
||||
UserpicButton(QWidget *parent, PeerData *peer, int size = 0);
|
||||
UserpicButton(QWidget *parent, not_null<PeerData*> peer, int size = 0);
|
||||
|
||||
// If at the first moment the _userpic was not loaded,
|
||||
// we need to show it animated after the profile is fully shown.
|
||||
|
@ -51,7 +51,7 @@ private:
|
|||
bool _notShownYet;
|
||||
|
||||
int _size = 0;
|
||||
PeerData *_peer;
|
||||
not_null<PeerData*> _peer;
|
||||
bool _waiting = false;
|
||||
QPixmap _userpic, _oldUserpic;
|
||||
Animation _a_appearance;
|
||||
|
|
|
@ -165,7 +165,7 @@ bool Widget::wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Windo
|
|||
return _scroll->viewportEvent(e);
|
||||
}
|
||||
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) {
|
||||
QRect Widget::rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const {
|
||||
return mapToGlobal(_scroll->geometry());
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
// Float player interface.
|
||||
bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override;
|
||||
QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) const override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
|
@ -143,8 +143,8 @@ std::weak_ptr<std::vector<consumer<Value, no_error>>> event_stream<Value>::weak(
|
|||
|
||||
template <typename Value>
|
||||
event_stream<Value>::~event_stream() {
|
||||
if (_consumers) {
|
||||
for (auto &consumer : *_consumers) {
|
||||
if (auto consumers = base::take(_consumers)) {
|
||||
for (auto &consumer : *consumers) {
|
||||
consumer.put_done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "boxes/local_storage_box.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
|
||||
|
@ -62,31 +62,31 @@ void AdvancedWidget::createControls() {
|
|||
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
})();
|
||||
if (self()) {
|
||||
addChildRow(_manageLocalStorage, marginLocalStorage, lang(lng_settings_manage_local_storage), SLOT(onManageLocalStorage()));
|
||||
createChildRow(_manageLocalStorage, marginLocalStorage, lang(lng_settings_manage_local_storage), SLOT(onManageLocalStorage()));
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
addChildRow(_connectionType, marginLarge, lang(lng_connection_type), lang(lng_connection_auto_connecting), LabeledLink::Type::Primary, SLOT(onConnectionType()));
|
||||
createChildRow(_connectionType, marginLarge, lang(lng_connection_type), lang(lng_connection_auto_connecting), LabeledLink::Type::Primary, SLOT(onConnectionType()));
|
||||
connectionTypeUpdated();
|
||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
|
||||
if (self()) {
|
||||
addChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion()));
|
||||
createChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion()));
|
||||
} else {
|
||||
style::margins slidedPadding(0, marginLarge.bottom() / 2, 0, marginLarge.bottom() - (marginLarge.bottom() / 2));
|
||||
addChildRow(_useDefaultTheme, marginLarge, slidedPadding, lang(lng_settings_bg_use_default), SLOT(onUseDefaultTheme()));
|
||||
createChildRow(_useDefaultTheme, marginLarge, slidedPadding, lang(lng_settings_bg_use_default), SLOT(onUseDefaultTheme()));
|
||||
if (!Window::Theme::IsNonDefaultUsed()) {
|
||||
_useDefaultTheme->hideFast();
|
||||
}
|
||||
addChildRow(_toggleNightTheme, marginLarge, slidedPadding, getNightThemeToggleText(), SLOT(onToggleNightTheme()));
|
||||
createChildRow(_toggleNightTheme, marginLarge, slidedPadding, getNightThemeToggleText(), SLOT(onToggleNightTheme()));
|
||||
if (Window::Theme::IsNonDefaultUsed()) {
|
||||
_toggleNightTheme->hideFast();
|
||||
}
|
||||
}
|
||||
addChildRow(_telegramFAQ, marginLarge, lang(lng_settings_faq), SLOT(onTelegramFAQ()));
|
||||
createChildRow(_telegramFAQ, marginLarge, lang(lng_settings_faq), SLOT(onTelegramFAQ()));
|
||||
if (self()) {
|
||||
style::margins marginLogout(0, 0, 0, 2 * st::settingsLargeSkip);
|
||||
addChildRow(_logOut, marginLogout, lang(lng_settings_logout), SLOT(onLogOut()));
|
||||
createChildRow(_logOut, marginLogout, lang(lng_settings_logout), SLOT(onLogOut()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,15 +52,15 @@ private:
|
|||
void supportGot(const MTPhelp_Support &support);
|
||||
QString getNightThemeToggleText() const;
|
||||
|
||||
object_ptr<Ui::LinkButton> _manageLocalStorage = { nullptr };
|
||||
Ui::LinkButton *_manageLocalStorage = nullptr;
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
object_ptr<LabeledLink> _connectionType = { nullptr };
|
||||
LabeledLink *_connectionType = nullptr;
|
||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _useDefaultTheme = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _toggleNightTheme = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _askQuestion = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _telegramFAQ = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _logOut = { nullptr };
|
||||
Ui::SlideWrap<Ui::LinkButton> *_useDefaultTheme = nullptr;
|
||||
Ui::SlideWrap<Ui::LinkButton> *_toggleNightTheme = nullptr;
|
||||
Ui::LinkButton *_askQuestion = nullptr;
|
||||
Ui::LinkButton *_telegramFAQ = nullptr;
|
||||
Ui::LinkButton *_logOut = nullptr;
|
||||
|
||||
mtpRequestId _supportGetRequest = 0;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "lang/lang_keys.h"
|
||||
#include "mainwidget.h"
|
||||
#include "boxes/background_box.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "storage/localstorage.h"
|
||||
|
@ -35,7 +35,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Settings {
|
||||
|
||||
BackgroundRow::BackgroundRow(QWidget *parent) : TWidget(parent)
|
||||
BackgroundRow::BackgroundRow(QWidget *parent) : RpWidget(parent)
|
||||
, _chooseFromGallery(this, lang(lng_settings_bg_from_gallery), st::boxLinkButton)
|
||||
, _chooseFromFile(this, lang(lng_settings_bg_from_file), st::boxLinkButton)
|
||||
, _editTheme(this, lang(lng_settings_bg_edit_theme), st::boxLinkButton)
|
||||
|
@ -216,14 +216,14 @@ void BackgroundWidget::createControls() {
|
|||
style::margins margin(0, 0, 0, st::settingsSmallSkip);
|
||||
style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2));
|
||||
|
||||
addChildRow(_background, margin);
|
||||
createChildRow(_background, margin);
|
||||
connect(_background, SIGNAL(chooseFromGallery()), this, SLOT(onChooseFromGallery()));
|
||||
connect(_background, SIGNAL(chooseFromFile()), this, SLOT(onChooseFromFile()));
|
||||
connect(_background, SIGNAL(editTheme()), this, SLOT(onEditTheme()));
|
||||
connect(_background, SIGNAL(useDefault()), this, SLOT(onUseDefaultTheme()));
|
||||
|
||||
addChildRow(_tile, margin, lang(lng_settings_bg_tile), [this](bool) { onTile(); }, Window::Theme::Background()->tile());
|
||||
addChildRow(_adaptive, margin, slidedPadding, lang(lng_settings_adaptive_wide), [this](bool) { onAdaptive(); }, Global::AdaptiveForWide());
|
||||
createChildRow(_tile, margin, lang(lng_settings_bg_tile), [this](bool) { onTile(); }, Window::Theme::Background()->tile());
|
||||
createChildRow(_adaptive, margin, slidedPadding, lang(lng_settings_adaptive_wide), [this](bool) { onAdaptive(); }, Global::AdaptiveForWide());
|
||||
if (Global::AdaptiveChatLayout() != Adaptive::ChatLayout::Wide) {
|
||||
_adaptive->hideFast();
|
||||
}
|
||||
|
|
|
@ -22,10 +22,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "settings/settings_block_widget.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class BackgroundRow : public TWidget, private base::Subscriber {
|
||||
class BackgroundRow : public Ui::RpWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -82,9 +83,9 @@ private:
|
|||
void createControls();
|
||||
void needBackgroundUpdate(bool tile);
|
||||
|
||||
object_ptr<BackgroundRow> _background = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _tile = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::Checkbox>> _adaptive = { nullptr };
|
||||
BackgroundRow *_background = nullptr;
|
||||
Ui::Checkbox *_tile = nullptr;
|
||||
Ui::SlideWrap<Ui::Checkbox> *_adaptive = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -23,12 +23,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "styles/style_settings.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
BlockWidget::BlockWidget(QWidget *parent, UserData *self, const QString &title) : TWidget(parent)
|
||||
BlockWidget::BlockWidget(QWidget *parent, UserData *self, const QString &title) : RpWidget(parent)
|
||||
, _self(self)
|
||||
, _title(title) {
|
||||
, _title(title)
|
||||
, _content(this) {
|
||||
_content->heightValue()
|
||||
| rpl::on_next([this](int contentHeight) {
|
||||
resize(width(), contentTop() + contentHeight + st::settingsBlockMarginBottom);
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void BlockWidget::setContentLeft(int contentLeft) {
|
||||
|
@ -42,21 +49,25 @@ int BlockWidget::contentTop() const {
|
|||
int BlockWidget::resizeGetHeight(int newWidth) {
|
||||
int x = contentLeft(), result = contentTop();
|
||||
int availw = newWidth - x;
|
||||
for_const (auto &row, _rows) {
|
||||
auto childMargins = row.child->getMargins();
|
||||
row.child->moveToLeft(x + row.margin.left(), result + row.margin.top(), newWidth);
|
||||
auto availRowWidth = availw - row.margin.left() - row.margin.right() - x;
|
||||
auto natural = row.child->naturalWidth();
|
||||
auto rowWidth = (natural < 0) ? availRowWidth : qMin(natural, availRowWidth);
|
||||
if (row.child->widthNoMargins() != rowWidth) {
|
||||
row.child->resizeToWidth(rowWidth);
|
||||
}
|
||||
result += row.margin.top() + row.child->heightNoMargins() + row.margin.bottom();
|
||||
}
|
||||
result += st::settingsBlockMarginBottom;
|
||||
|
||||
auto margins = getMargins();
|
||||
|
||||
_content->resizeToWidth(availw);
|
||||
_content->moveToLeft(margins.left() + x, margins.top() + result, newWidth);
|
||||
result += _content->heightNoMargins() + st::settingsBlockMarginBottom;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QMargins BlockWidget::getMargins() const {
|
||||
auto result = _content->getMargins();
|
||||
return QMargins(
|
||||
result.left(),
|
||||
qMax(result.top() - contentTop(), 0),
|
||||
result.right(),
|
||||
qMax(result.bottom() - st::settingsBlockMarginBottom, 0));
|
||||
}
|
||||
|
||||
void BlockWidget::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
|
@ -69,28 +80,37 @@ void BlockWidget::paintTitle(Painter &p) {
|
|||
|
||||
p.setFont(st::settingsBlockTitleFont);
|
||||
p.setPen(st::settingsBlockTitleFg);
|
||||
int titleTop = st::settingsBlockMarginTop + st::settingsBlockTitleTop;
|
||||
p.drawTextLeft(contentLeft(), titleTop, width(), _title);
|
||||
auto margins = getMargins();
|
||||
auto titleTop = st::settingsBlockMarginTop + st::settingsBlockTitleTop;
|
||||
p.drawTextLeft(
|
||||
margins.left() + contentLeft(),
|
||||
margins.top() + titleTop,
|
||||
width(),
|
||||
_title);
|
||||
}
|
||||
|
||||
void BlockWidget::addCreatedRow(TWidget *child, const style::margins &margin) {
|
||||
_rows.push_back({ child, margin });
|
||||
Ui::RpWidget *BlockWidget::addCreatedRow(
|
||||
object_ptr<RpWidget> row,
|
||||
const style::margins &margin) {
|
||||
return _content->add(std::move(row), margin);
|
||||
}
|
||||
|
||||
void BlockWidget::rowHeightUpdated() {
|
||||
auto newHeight = resizeGetHeight(width());
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
emit heightUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
void BlockWidget::createChildRow(object_ptr<Ui::Checkbox> &child, style::margins &margin, const QString &text, base::lambda<void(bool checked)> callback, bool checked) {
|
||||
void BlockWidget::createChildWidget(
|
||||
object_ptr<Ui::Checkbox> &child,
|
||||
style::margins &margin,
|
||||
const QString &text,
|
||||
base::lambda<void(bool checked)> callback,
|
||||
bool checked) {
|
||||
child.create(this, text, checked, st::defaultBoxCheckbox);
|
||||
subscribe(child->checkedChanged, std::move(callback));
|
||||
}
|
||||
|
||||
void BlockWidget::createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st) {
|
||||
void BlockWidget::createChildWidget(
|
||||
object_ptr<Ui::LinkButton> &child,
|
||||
style::margins &margin,
|
||||
const QString &text,
|
||||
const char *slot,
|
||||
const style::LinkButton &st) {
|
||||
child.create(this, text, st);
|
||||
connect(child, SIGNAL(clicked()), this, slot);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "base/observer.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
namespace Ui {
|
||||
|
@ -33,19 +34,20 @@ class RadioenumGroup;
|
|||
template <typename Enum>
|
||||
class Radioenum;
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap;
|
||||
class SlideWrap;
|
||||
class VerticalLayout;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class BlockWidget : public TWidget, protected base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
class BlockWidget : public Ui::RpWidget, protected base::Subscriber {
|
||||
public:
|
||||
BlockWidget(QWidget *parent, UserData *self, const QString &title);
|
||||
|
||||
void setContentLeft(int contentLeft);
|
||||
|
||||
QMargins getMargins() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
virtual void paintContents(Painter &p) {
|
||||
|
@ -60,11 +62,6 @@ protected:
|
|||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
void contentSizeUpdated() {
|
||||
resizeToWidth(width());
|
||||
emit heightUpdated();
|
||||
}
|
||||
|
||||
UserData *self() const {
|
||||
return _self;
|
||||
}
|
||||
|
@ -74,39 +71,67 @@ protected:
|
|||
}
|
||||
|
||||
template <typename Widget, typename ...Args>
|
||||
Widget *addChildRow(object_ptr<Widget> &child, style::margins margin, Args&&... args) {
|
||||
createChildRow(child, margin, std::forward<Args>(args)...);
|
||||
addCreatedRow(child, margin);
|
||||
return child;
|
||||
void createChildRow(
|
||||
Widget *&child,
|
||||
style::margins margin,
|
||||
Args&&... args) {
|
||||
auto row = object_ptr<Widget>{ nullptr };
|
||||
createChildWidget(row, margin, std::forward<Args>(args)...);
|
||||
child = static_cast<Widget*>(addCreatedRow(
|
||||
std::move(row),
|
||||
margin));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Widget, typename ...Args>
|
||||
void createChildRow(object_ptr<Ui::WidgetSlideWrap<Widget>> &child, style::margins &margin, const style::margins &padding, Args&&... args) {
|
||||
void createChildWidget(
|
||||
object_ptr<Ui::SlideWrap<Widget>> &child,
|
||||
style::margins &margin,
|
||||
const style::margins &padding,
|
||||
Args&&... args) {
|
||||
object_ptr<Widget> entity = { nullptr };
|
||||
createChildRow(entity, margin, std::forward<Args>(args)...);
|
||||
child.create(this, std::move(entity), padding, [this] { rowHeightUpdated(); });
|
||||
createChildWidget(entity, margin, std::forward<Args>(args)...);
|
||||
child.create(this, std::move(entity), padding);
|
||||
margin.setLeft(margin.left() - padding.left());
|
||||
margin.setTop(margin.top() - padding.top());
|
||||
margin.setRight(margin.right() - padding.right());
|
||||
margin.setBottom(margin.bottom() - padding.bottom());
|
||||
}
|
||||
void createChildRow(object_ptr<Ui::Checkbox> &child, style::margins &margin, const QString &text, base::lambda<void(bool checked)> callback, bool checked);
|
||||
void createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st = st::boxLinkButton);
|
||||
void createChildWidget(
|
||||
object_ptr<Ui::Checkbox> &child,
|
||||
style::margins &margin,
|
||||
const QString &text, base::lambda<void(bool checked)> callback, bool checked);
|
||||
void createChildWidget(
|
||||
object_ptr<Ui::LinkButton> &child,
|
||||
style::margins &margin,
|
||||
const QString &text,
|
||||
const char *slot,
|
||||
const style::LinkButton &st = st::boxLinkButton);
|
||||
|
||||
template <typename Enum>
|
||||
void createChildRow(object_ptr<Ui::Radioenum<Enum>> &child, style::margins &margin, const std::shared_ptr<Ui::RadioenumGroup<Enum>> &group, Enum value, const QString &text) {
|
||||
child.create(this, group, value, text, st::defaultBoxCheckbox);
|
||||
void createChildWidget(
|
||||
object_ptr<Ui::Radioenum<Enum>> &child,
|
||||
style::margins &margin,
|
||||
const std::shared_ptr<Ui::RadioenumGroup<Enum>> &group,
|
||||
Enum value,
|
||||
const QString &text) {
|
||||
child.create(
|
||||
this,
|
||||
group,
|
||||
value,
|
||||
text,
|
||||
st::defaultBoxCheckbox);
|
||||
}
|
||||
|
||||
void addCreatedRow(TWidget *child, const style::margins &margin);
|
||||
void rowHeightUpdated();
|
||||
RpWidget *addCreatedRow(
|
||||
object_ptr<RpWidget> row,
|
||||
const style::margins &margin);
|
||||
|
||||
template <typename Widget>
|
||||
struct IsWidgetSlideWrap : std::false_type {
|
||||
struct IsSlideWrap : std::false_type {
|
||||
};
|
||||
template <typename Widget>
|
||||
struct IsWidgetSlideWrap<Ui::WidgetSlideWrap<Widget>> : std::true_type {
|
||||
struct IsSlideWrap<Ui::SlideWrap<Widget>> : std::true_type {
|
||||
};
|
||||
template <typename Widget>
|
||||
struct IsRadioenum : std::false_type {
|
||||
|
@ -117,23 +142,19 @@ private:
|
|||
|
||||
template <typename Widget>
|
||||
using NotImplementedYet = std::enable_if_t<
|
||||
!IsWidgetSlideWrap<Widget>::value &&
|
||||
!IsSlideWrap<Widget>::value &&
|
||||
!IsRadioenum<Widget>::value &&
|
||||
!std::is_same<Ui::Checkbox, Widget>::value &&
|
||||
!std::is_same<Ui::LinkButton, Widget>::value>;
|
||||
|
||||
template <typename Widget, typename... Args, typename = NotImplementedYet<Widget>>
|
||||
void createChildRow(object_ptr<Widget> &child, style::margins &margin, Args&&... args) {
|
||||
void createChildWidget(object_ptr<Widget> &child, style::margins &margin, Args&&... args) {
|
||||
child.create(this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void paintTitle(Painter &p);
|
||||
|
||||
struct ChildRow {
|
||||
TWidget *child;
|
||||
style::margins margin;
|
||||
};
|
||||
QVector<ChildRow> _rows;
|
||||
object_ptr<Ui::VerticalLayout> _content;
|
||||
|
||||
int _contentLeft = 0;
|
||||
UserData *_self;
|
||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "styles/style_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
|
@ -36,7 +36,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Settings {
|
||||
|
||||
LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot) : TWidget(parent)
|
||||
LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text, Type type, const char *slot) : RpWidget(parent)
|
||||
, _label(this, label, Ui::FlatLabel::InitType::Simple, (type == Type::Primary) ? st::settingsPrimaryLabel : st::defaultFlatLabel)
|
||||
, _link(this, text, (type == Type::Primary) ? st::boxLinkButton : st::defaultLinkButton) {
|
||||
connect(_link, SIGNAL(clicked()), parent, slot);
|
||||
|
@ -58,7 +58,7 @@ int LabeledLink::resizeGetHeight(int newWidth) {
|
|||
}
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
DownloadPathState::DownloadPathState(QWidget *parent) : TWidget(parent)
|
||||
DownloadPathState::DownloadPathState(QWidget *parent) : RpWidget(parent)
|
||||
, _path(this, lang(lng_download_path_label), downloadPathText(), LabeledLink::Type::Secondary, SLOT(onDownloadPath()))
|
||||
, _clear(this, lang(lng_download_path_clear)) {
|
||||
connect(_clear, SIGNAL(clicked()), this, SLOT(onClear()));
|
||||
|
@ -153,32 +153,32 @@ void ChatSettingsWidget::createControls() {
|
|||
style::margins marginSub(0, 0, 0, st::settingsSubSkip);
|
||||
style::margins slidedPadding(0, marginSub.bottom() / 2, 0, marginSub.bottom() - (marginSub.bottom() / 2));
|
||||
|
||||
addChildRow(_replaceEmoji, marginSkip, lang(lng_settings_replace_emojis), [this](bool) { onReplaceEmoji(); }, cReplaceEmojis());
|
||||
createChildRow(_replaceEmoji, marginSkip, lang(lng_settings_replace_emojis), [this](bool) { onReplaceEmoji(); }, cReplaceEmojis());
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
auto pathMargin = marginSub;
|
||||
#else // OS_WIN_STORE
|
||||
auto pathMargin = marginSkip;
|
||||
#endif // OS_WIN_STORE
|
||||
addChildRow(_dontAskDownloadPath, pathMargin, lang(lng_download_path_dont_ask), [this](bool) { onDontAskDownloadPath(); }, !Global::AskDownloadPath());
|
||||
createChildRow(_dontAskDownloadPath, pathMargin, lang(lng_download_path_dont_ask), [this](bool) { onDontAskDownloadPath(); }, !Global::AskDownloadPath());
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
style::margins marginPath(st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip);
|
||||
addChildRow(_downloadPath, marginPath, slidedPadding);
|
||||
createChildRow(_downloadPath, marginPath, slidedPadding);
|
||||
if (Global::AskDownloadPath()) {
|
||||
_downloadPath->hideFast();
|
||||
}
|
||||
#endif // OS_WIN_STORE
|
||||
|
||||
auto group = std::make_shared<Ui::RadioenumGroup<SendByType>>(cCtrlEnter() ? SendByType::CtrlEnter : SendByType::Enter);
|
||||
addChildRow(_sendByEnter, marginSmall, group, SendByType::Enter, lang(lng_settings_send_enter));
|
||||
addChildRow(_sendByCtrlEnter, marginSkip, group, SendByType::CtrlEnter, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter));
|
||||
createChildRow(_sendByEnter, marginSmall, group, SendByType::Enter, lang(lng_settings_send_enter));
|
||||
createChildRow(_sendByCtrlEnter, marginSkip, group, SendByType::CtrlEnter, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter));
|
||||
group->setChangedCallback([this](SendByType value) {
|
||||
sendByChanged(value);
|
||||
});
|
||||
|
||||
addChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings()));
|
||||
addChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets()));
|
||||
createChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings()));
|
||||
createChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets()));
|
||||
}
|
||||
|
||||
void ChatSettingsWidget::onReplaceEmoji() {
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "settings/settings_block_widget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class FlatLabel;
|
||||
|
@ -28,7 +29,7 @@ class FlatLabel;
|
|||
|
||||
namespace Settings {
|
||||
|
||||
class LabeledLink : public TWidget {
|
||||
class LabeledLink : public Ui::RpWidget {
|
||||
public:
|
||||
enum class Type {
|
||||
Primary,
|
||||
|
@ -50,7 +51,7 @@ private:
|
|||
};
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
class DownloadPathState : public TWidget, private base::Subscriber {
|
||||
class DownloadPathState : public Ui::RpWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -106,17 +107,17 @@ private:
|
|||
void sendByChanged(SendByType value);
|
||||
void createControls();
|
||||
|
||||
object_ptr<Ui::Checkbox> _replaceEmoji = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _dontAskDownloadPath = { nullptr };
|
||||
Ui::Checkbox *_replaceEmoji = nullptr;
|
||||
Ui::Checkbox *_dontAskDownloadPath = nullptr;
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
object_ptr<Ui::WidgetSlideWrap<DownloadPathState>> _downloadPath = { nullptr };
|
||||
Ui::SlideWrap<DownloadPathState> *_downloadPath = nullptr;
|
||||
#endif // OS_WIN_STORE
|
||||
|
||||
object_ptr<Ui::Radioenum<SendByType>> _sendByEnter = { nullptr };
|
||||
object_ptr<Ui::Radioenum<SendByType>> _sendByCtrlEnter = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _automaticMediaDownloadSettings = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _manageStickerSets = { nullptr };
|
||||
Ui::Radioenum<SendByType> *_sendByEnter = nullptr;
|
||||
Ui::Radioenum<SendByType> *_sendByCtrlEnter = nullptr;
|
||||
Ui::LinkButton *_automaticMediaDownloadSettings = nullptr;
|
||||
Ui::LinkButton *_manageStickerSets = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -101,12 +101,22 @@ int CoverWidget::resizeGetHeight(int newWidth) {
|
|||
|
||||
newHeight += st::settingsMarginTop;
|
||||
|
||||
_userpicButton->moveToLeft(contentLeft() + st::settingsPhotoLeft, newHeight, newWidth);
|
||||
auto margins = getMargins();
|
||||
_userpicButton->moveToLeft(
|
||||
margins.left() + contentLeft() + st::settingsPhotoLeft,
|
||||
margins.top() + newHeight,
|
||||
newWidth);
|
||||
|
||||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
_statusPosition = QPoint(infoLeft + st::settingsStatusLeft, _userpicButton->y() + st::settingsStatusTop);
|
||||
if (_cancelPhotoUpload) {
|
||||
_cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::settingsStatusFont->width(_statusText) + st::settingsStatusFont->spacew, _statusPosition.y(), newWidth);
|
||||
_cancelPhotoUpload->moveToLeft(
|
||||
margins.left()
|
||||
+ _statusPosition.x()
|
||||
+ st::settingsStatusFont->width(_statusText)
|
||||
+ st::settingsStatusFont->spacew,
|
||||
margins.top() + _statusPosition.y(),
|
||||
newWidth);
|
||||
}
|
||||
|
||||
refreshButtonsGeometry(newWidth);
|
||||
|
@ -125,20 +135,27 @@ int CoverWidget::resizeGetHeight(int newWidth) {
|
|||
}
|
||||
|
||||
void CoverWidget::refreshButtonsGeometry(int newWidth) {
|
||||
int buttonLeft = _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft;
|
||||
int buttonsRight = newWidth - st::settingsButtonSkip;
|
||||
_setPhoto->moveToLeft(buttonLeft, _userpicButton->y() + st::settingsButtonTop, newWidth);
|
||||
auto margins = getMargins();
|
||||
auto buttonLeft = margins.left() + _userpicButton->x() + _userpicButton->width() + st::settingsButtonLeft;
|
||||
_setPhoto->moveToLeft(
|
||||
buttonLeft,
|
||||
margins.top() + _userpicButton->y() + st::settingsButtonTop,
|
||||
newWidth);
|
||||
buttonLeft += _setPhoto->width() + st::settingsButtonSkip;
|
||||
_editName->moveToLeft(buttonLeft, _setPhoto->y(), newWidth);
|
||||
_editName->moveToLeft(
|
||||
buttonLeft,
|
||||
margins.top() + _setPhoto->y(),
|
||||
newWidth);
|
||||
_editNameVisible = (buttonLeft + _editName->width() + st::settingsButtonSkip <= newWidth);
|
||||
_editName->setVisible(_editNameVisible);
|
||||
}
|
||||
|
||||
void CoverWidget::refreshNameGeometry(int newWidth) {
|
||||
int infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
int nameLeft = infoLeft + st::settingsNameLeft - st::settingsNameLabel.margin.left();
|
||||
int nameTop = _userpicButton->y() + st::settingsNameTop - st::settingsNameLabel.margin.top();
|
||||
int nameWidth = newWidth - infoLeft - st::settingsNameLeft;
|
||||
auto margins = getMargins();
|
||||
auto infoLeft = _userpicButton->x() + _userpicButton->width();
|
||||
auto nameLeft = infoLeft + st::settingsNameLeft - st::settingsNameLabel.margin.left();
|
||||
auto nameTop = _userpicButton->y() + st::settingsNameTop - st::settingsNameLabel.margin.top();
|
||||
auto nameWidth = newWidth - infoLeft - st::settingsNameLeft;
|
||||
auto editNameInlineVisible = !_editNameVisible;
|
||||
if (editNameInlineVisible) {
|
||||
nameWidth -= _editNameInline->width();
|
||||
|
@ -146,9 +163,15 @@ void CoverWidget::refreshNameGeometry(int newWidth) {
|
|||
int marginsAdd = st::settingsNameLabel.margin.left() + st::settingsNameLabel.margin.right();
|
||||
|
||||
_name->resizeToWidth(qMin(nameWidth - marginsAdd, _name->naturalWidth()) + marginsAdd);
|
||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||
_name->moveToLeft(
|
||||
margins.left() + nameLeft,
|
||||
margins.top() + nameTop,
|
||||
newWidth);
|
||||
|
||||
_editNameInline->moveToLeft(nameLeft + _name->width(), nameTop, newWidth);
|
||||
_editNameInline->moveToLeft(
|
||||
margins.left() + nameLeft + _name->width(),
|
||||
margins.top() + nameTop,
|
||||
newWidth);
|
||||
_editNameInline->setVisible(editNameInlineVisible);
|
||||
}
|
||||
|
||||
|
@ -283,10 +306,16 @@ void CoverWidget::refreshStatusText() {
|
|||
_statusText = lang(lng_settings_uploading_photo);
|
||||
_statusTextIsOnline = false;
|
||||
if (!_cancelPhotoUpload) {
|
||||
auto margins = getMargins();
|
||||
_cancelPhotoUpload.create(this, lang(lng_cancel), st::defaultLinkButton);
|
||||
connect(_cancelPhotoUpload, SIGNAL(clicked()), this, SLOT(onCancelPhotoUpload()));
|
||||
_cancelPhotoUpload->show();
|
||||
_cancelPhotoUpload->moveToLeft(_statusPosition.x() + st::settingsStatusFont->width(_statusText) + st::settingsStatusFont->spacew, _statusPosition.y());
|
||||
_cancelPhotoUpload->moveToLeft(
|
||||
margins.left()
|
||||
+ _statusPosition.x()
|
||||
+ st::settingsStatusFont->width(_statusText)
|
||||
+ st::settingsStatusFont->spacew,
|
||||
margins.top() + _statusPosition.y());
|
||||
}
|
||||
update();
|
||||
return;
|
||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "styles/style_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "storage/localstorage.h"
|
||||
|
@ -41,7 +41,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
namespace Settings {
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
UpdateStateRow::UpdateStateRow(QWidget *parent) : TWidget(parent)
|
||||
UpdateStateRow::UpdateStateRow(QWidget *parent) : RpWidget(parent)
|
||||
, _check(this, lang(lng_settings_check_now))
|
||||
, _restart(this, lang(lng_settings_update_now)) {
|
||||
connect(_check, SIGNAL(clicked()), this, SLOT(onCheck()));
|
||||
|
@ -164,7 +164,7 @@ GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(pare
|
|||
}
|
||||
|
||||
int GeneralWidget::resizeGetHeight(int newWidth) {
|
||||
_changeLanguage->moveToRight(contentLeft(), st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::defaultLinkButton.font->ascent, newWidth);
|
||||
_changeLanguage->moveToRight(0, st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::defaultLinkButton.font->ascent, newWidth);
|
||||
return BlockWidget::resizeGetHeight(newWidth);
|
||||
}
|
||||
|
||||
|
@ -175,9 +175,9 @@ void GeneralWidget::refreshControls() {
|
|||
style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
addChildRow(_updateAutomatically, marginSub, lang(lng_settings_update_automatically), [this](bool) { onUpdateAutomatically(); }, cAutoUpdate());
|
||||
createChildRow(_updateAutomatically, marginSub, lang(lng_settings_update_automatically), [this](bool) { onUpdateAutomatically(); }, cAutoUpdate());
|
||||
style::margins marginLink(st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip);
|
||||
addChildRow(_updateRow, marginLink, slidedPadding);
|
||||
createChildRow(_updateRow, marginLink, slidedPadding);
|
||||
connect(_updateRow->entity(), SIGNAL(restart()), this, SLOT(onRestart()));
|
||||
if (!cAutoUpdate()) {
|
||||
_updateRow->hideFast();
|
||||
|
@ -186,20 +186,20 @@ void GeneralWidget::refreshControls() {
|
|||
|
||||
if (cPlatform() == dbipWindows || cSupportTray()) {
|
||||
auto workMode = Global::WorkMode().value();
|
||||
addChildRow(_enableTrayIcon, marginSmall, lang(lng_settings_workmode_tray), [this](bool) { onEnableTrayIcon(); }, (workMode == dbiwmTrayOnly || workMode == dbiwmWindowAndTray));
|
||||
createChildRow(_enableTrayIcon, marginSmall, lang(lng_settings_workmode_tray), [this](bool) { onEnableTrayIcon(); }, (workMode == dbiwmTrayOnly || workMode == dbiwmWindowAndTray));
|
||||
if (cPlatform() == dbipWindows) {
|
||||
addChildRow(_enableTaskbarIcon, marginLarge, lang(lng_settings_workmode_window), [this](bool) { onEnableTaskbarIcon(); }, (workMode == dbiwmWindowOnly || workMode == dbiwmWindowAndTray));
|
||||
createChildRow(_enableTaskbarIcon, marginLarge, lang(lng_settings_workmode_window), [this](bool) { onEnableTaskbarIcon(); }, (workMode == dbiwmWindowOnly || workMode == dbiwmWindowAndTray));
|
||||
|
||||
#ifndef OS_WIN_STORE
|
||||
addChildRow(_autoStart, marginSmall, lang(lng_settings_auto_start), [this](bool) { onAutoStart(); }, cAutoStart());
|
||||
addChildRow(_startMinimized, marginLarge, slidedPadding, lang(lng_settings_start_min), [this](bool) { onStartMinimized(); }, (cStartMinimized() && !Global::LocalPasscode()));
|
||||
createChildRow(_autoStart, marginSmall, lang(lng_settings_auto_start), [this](bool) { onAutoStart(); }, cAutoStart());
|
||||
createChildRow(_startMinimized, marginLarge, slidedPadding, lang(lng_settings_start_min), [this](bool) { onStartMinimized(); }, (cStartMinimized() && !Global::LocalPasscode()));
|
||||
subscribe(Global::RefLocalPasscodeChanged(), [this] {
|
||||
_startMinimized->entity()->setChecked(cStartMinimized() && !Global::LocalPasscode());
|
||||
});
|
||||
if (!cAutoStart()) {
|
||||
_startMinimized->hideFast();
|
||||
}
|
||||
addChildRow(_addInSendTo, marginSmall, lang(lng_settings_add_sendto), [this](bool) { onAddInSendTo(); }, cSendToMenu());
|
||||
createChildRow(_addInSendTo, marginSmall, lang(lng_settings_add_sendto), [this](bool) { onAddInSendTo(); }, cSendToMenu());
|
||||
#endif // OS_WIN_STORE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "settings/settings_block_widget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
class UpdateStateRow : public TWidget {
|
||||
class UpdateStateRow : public Ui::RpWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -107,14 +108,14 @@ private:
|
|||
|
||||
object_ptr<Ui::LinkButton> _changeLanguage;
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
object_ptr<Ui::Checkbox> _updateAutomatically = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<UpdateStateRow>> _updateRow = { nullptr };
|
||||
Ui::Checkbox *_updateAutomatically = nullptr;
|
||||
Ui::SlideWrap<UpdateStateRow> *_updateRow = nullptr;
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
object_ptr<Ui::Checkbox> _enableTrayIcon = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _enableTaskbarIcon = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _autoStart = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::Checkbox>> _startMinimized = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _addInSendTo = { nullptr };
|
||||
Ui::Checkbox *_enableTrayIcon = nullptr;
|
||||
Ui::Checkbox *_enableTaskbarIcon = nullptr;
|
||||
Ui::Checkbox *_autoStart = nullptr;
|
||||
Ui::SlideWrap<Ui::Checkbox> *_startMinimized = nullptr;
|
||||
Ui::Checkbox *_addInSendTo = nullptr;
|
||||
|
||||
int _languagesLoadedSubscription = 0;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "styles/style_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "boxes/username_box.h"
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/change_phone_box.h"
|
||||
|
@ -46,9 +46,9 @@ InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, se
|
|||
void InfoWidget::createControls() {
|
||||
style::margins margin(0, 0, 0, 0);
|
||||
style::margins slidedPadding(0, 0, 0, 0);
|
||||
addChildRow(_mobileNumber, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
||||
addChildRow(_username, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
||||
addChildRow(_bio, margin, slidedPadding, st::settingsBioValue);
|
||||
createChildRow(_mobileNumber, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
||||
createChildRow(_username, margin, slidedPadding, st::settingsBlockOneLineTextPart);
|
||||
createChildRow(_bio, margin, slidedPadding, st::settingsBioValue);
|
||||
refreshControls();
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,12 @@ void InfoWidget::refreshMobileNumber() {
|
|||
phoneText.text = App::phoneFromSharedContact(peerToUser(user->id));
|
||||
}
|
||||
}
|
||||
setLabeledText(_mobileNumber, lang(lng_profile_mobile_number), phoneText, TextWithEntities(), lang(lng_profile_copy_phone));
|
||||
setLabeledText(
|
||||
_mobileNumber,
|
||||
lang(lng_profile_mobile_number),
|
||||
phoneText,
|
||||
TextWithEntities(),
|
||||
lang(lng_profile_copy_phone));
|
||||
if (auto text = _mobileNumber->entity()->textLabel()) {
|
||||
text->setRichText(textcmdLink(1, phoneText.text));
|
||||
text->setLink(1, MakeShared<LambdaClickHandler>([] {
|
||||
|
@ -86,7 +91,12 @@ void InfoWidget::refreshUsername() {
|
|||
copyText = lang(lng_context_copy_mention);
|
||||
}
|
||||
usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size(), Messenger::Instance().createInternalLinkFull(self()->username)));
|
||||
setLabeledText(_username, lang(lng_profile_username), usernameText, TextWithEntities(), copyText);
|
||||
setLabeledText(
|
||||
_username,
|
||||
lang(lng_profile_username),
|
||||
usernameText,
|
||||
TextWithEntities(),
|
||||
copyText);
|
||||
if (auto text = _username->entity()->textLabel()) {
|
||||
text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
Ui::show(Box<UsernameBox>());
|
||||
|
@ -104,7 +114,12 @@ void InfoWidget::refreshBio() {
|
|||
bioText.text = aboutText;
|
||||
}
|
||||
bioText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, bioText.text.size(), QString()));
|
||||
setLabeledText(_bio, lang(lng_profile_bio), bioText, TextWithEntities(), QString());
|
||||
setLabeledText(
|
||||
_bio,
|
||||
lang(lng_profile_bio),
|
||||
bioText,
|
||||
TextWithEntities(),
|
||||
QString());
|
||||
if (auto text = _bio->entity()->textLabel()) {
|
||||
text->setClickHandlerHook([](const ClickHandlerPtr &handler, Qt::MouseButton button) {
|
||||
Ui::show(Box<EditBioBox>(App::self()));
|
||||
|
@ -113,19 +128,34 @@ void InfoWidget::refreshBio() {
|
|||
}
|
||||
}
|
||||
|
||||
void InfoWidget::setLabeledText(object_ptr<LabeledWrap> &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) {
|
||||
void InfoWidget::setLabeledText(
|
||||
LabeledWrap *row,
|
||||
const QString &label,
|
||||
const TextWithEntities &textWithEntities,
|
||||
const TextWithEntities &shortTextWithEntities,
|
||||
const QString ©Text) {
|
||||
auto nonEmptyText = !textWithEntities.text.isEmpty();
|
||||
if (nonEmptyText) {
|
||||
row->entity()->setLabeledText(label, textWithEntities, shortTextWithEntities, copyText);
|
||||
row->entity()->setLabeledText(
|
||||
label,
|
||||
textWithEntities,
|
||||
shortTextWithEntities,
|
||||
copyText,
|
||||
width());
|
||||
}
|
||||
row->toggleAnimated(nonEmptyText);
|
||||
}
|
||||
|
||||
InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent, const style::FlatLabel &valueSt) : TWidget(parent)
|
||||
InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent, const style::FlatLabel &valueSt) : RpWidget(parent)
|
||||
, _valueSt(valueSt) {
|
||||
}
|
||||
|
||||
void InfoWidget::LabeledWidget::setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) {
|
||||
void InfoWidget::LabeledWidget::setLabeledText(
|
||||
const QString &label,
|
||||
const TextWithEntities &textWithEntities,
|
||||
const TextWithEntities &shortTextWithEntities,
|
||||
const QString ©Text,
|
||||
int availableWidth) {
|
||||
_label.destroy();
|
||||
_text.destroy();
|
||||
_shortText.destroy();
|
||||
|
@ -135,7 +165,7 @@ void InfoWidget::LabeledWidget::setLabeledText(const QString &label, const TextW
|
|||
_label->show();
|
||||
setLabelText(_text, textWithEntities, copyText);
|
||||
setLabelText(_shortText, shortTextWithEntities, copyText);
|
||||
resizeToWidth(width());
|
||||
resizeToNaturalWidth(availableWidth);
|
||||
}
|
||||
|
||||
Ui::FlatLabel *InfoWidget::LabeledWidget::textLabel() const {
|
||||
|
@ -172,8 +202,6 @@ void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
|||
if (update.flags & UpdateFlag::AboutChanged) {
|
||||
refreshBio();
|
||||
}
|
||||
|
||||
contentSizeUpdated();
|
||||
}
|
||||
|
||||
int InfoWidget::LabeledWidget::naturalWidth() const {
|
||||
|
@ -188,10 +216,7 @@ int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) {
|
|||
if (!_label) return 0;
|
||||
|
||||
_label->moveToLeft(0, st::settingsBlockOneLineTextPart.margin.top(), newWidth);
|
||||
auto labelNatural = _label->naturalWidth();
|
||||
Assert(labelNatural >= 0);
|
||||
|
||||
_label->resize(qMin(newWidth, labelNatural), _label->height());
|
||||
_label->resizeToNaturalWidth(newWidth);
|
||||
|
||||
int textLeft = _label->width() + st::normalFont->spacew;
|
||||
int textWidth = _text->naturalWidth();
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "settings/settings_block_widget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class FlatLabel;
|
||||
|
@ -46,11 +47,16 @@ private:
|
|||
void refreshUsername();
|
||||
void refreshBio();
|
||||
|
||||
class LabeledWidget : public TWidget {
|
||||
class LabeledWidget : public Ui::RpWidget {
|
||||
public:
|
||||
LabeledWidget(QWidget *parent, const style::FlatLabel &valueSt);
|
||||
|
||||
void setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text);
|
||||
void setLabeledText(
|
||||
const QString &label,
|
||||
const TextWithEntities &textWithEntities,
|
||||
const TextWithEntities &shortTextWithEntities,
|
||||
const QString ©Text,
|
||||
int availableWidth);
|
||||
|
||||
Ui::FlatLabel *textLabel() const;
|
||||
Ui::FlatLabel *shortTextLabel() const;
|
||||
|
@ -61,7 +67,10 @@ private:
|
|||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void setLabelText(object_ptr<Ui::FlatLabel> &text, const TextWithEntities &textWithEntities, const QString ©Text);
|
||||
void setLabelText(
|
||||
object_ptr<Ui::FlatLabel> &text,
|
||||
const TextWithEntities &textWithEntities,
|
||||
const QString ©Text);
|
||||
|
||||
const style::FlatLabel &_valueSt;
|
||||
object_ptr<Ui::FlatLabel> _label = { nullptr };
|
||||
|
@ -70,12 +79,17 @@ private:
|
|||
|
||||
};
|
||||
|
||||
using LabeledWrap = Ui::WidgetSlideWrap<LabeledWidget>;
|
||||
void setLabeledText(object_ptr<LabeledWrap> &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text);
|
||||
using LabeledWrap = Ui::SlideWrap<LabeledWidget>;
|
||||
void setLabeledText(
|
||||
LabeledWrap *row,
|
||||
const QString &label,
|
||||
const TextWithEntities &textWithEntities,
|
||||
const TextWithEntities &shortTextWithEntities,
|
||||
const QString ©Text);
|
||||
|
||||
object_ptr<LabeledWrap> _mobileNumber = { nullptr };
|
||||
object_ptr<LabeledWrap> _username = { nullptr };
|
||||
object_ptr<LabeledWrap> _bio = { nullptr };
|
||||
LabeledWrap *_mobileNumber = nullptr;
|
||||
LabeledWrap *_username = nullptr;
|
||||
LabeledWrap *_bio = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
namespace Settings {
|
||||
|
||||
InnerWidget::InnerWidget(QWidget *parent) : LayerInner(parent)
|
||||
, _self(App::self()) {
|
||||
, _self(App::self())
|
||||
, _blocks(this) {
|
||||
refreshBlocks();
|
||||
subscribe(Global::RefSelfChanged(), [this] { fullRebuild(); });
|
||||
subscribe(Lang::Current().updated(), [this] { fullRebuild(); });
|
||||
|
@ -45,44 +46,34 @@ InnerWidget::InnerWidget(QWidget *parent) : LayerInner(parent)
|
|||
void InnerWidget::fullRebuild() {
|
||||
_self = App::self();
|
||||
refreshBlocks();
|
||||
|
||||
if (_cover) {
|
||||
_cover->setContentLeft(_contentLeft);
|
||||
_cover->resizeToWidth(width());
|
||||
}
|
||||
for_const (auto block, _blocks) {
|
||||
block->setContentLeft(_contentLeft);
|
||||
block->resizeToWidth(width());
|
||||
}
|
||||
onBlockHeightUpdated();
|
||||
}
|
||||
|
||||
void InnerWidget::refreshBlocks() {
|
||||
_cover.destroyDelayed();
|
||||
for_const (auto block, _blocks) {
|
||||
block->hide();
|
||||
block->deleteLater();
|
||||
}
|
||||
_blocks.clear();
|
||||
|
||||
if (App::quitting()) {
|
||||
_cover.destroy();
|
||||
_blocks.destroy();
|
||||
return;
|
||||
}
|
||||
_cover = _self
|
||||
? object_ptr<CoverWidget>(this, _self)
|
||||
: nullptr;
|
||||
_blocks = object_ptr<Ui::VerticalLayout>(this);
|
||||
resizeToWidth(width(), _contentLeft);
|
||||
|
||||
if (_self) {
|
||||
_cover.create(this, _self);
|
||||
_blocks.push_back(new InfoWidget(this, _self));
|
||||
_blocks.push_back(new NotificationsWidget(this, _self));
|
||||
_blocks->add(object_ptr<InfoWidget>(this, _self));
|
||||
_blocks->add(object_ptr<NotificationsWidget>(this, _self));
|
||||
}
|
||||
_blocks.push_back(new GeneralWidget(this, _self));
|
||||
_blocks->add(object_ptr<GeneralWidget>(this, _self));
|
||||
if (!cRetina()) {
|
||||
_blocks.push_back(new ScaleWidget(this, _self));
|
||||
_blocks->add(object_ptr<ScaleWidget>(this, _self));
|
||||
}
|
||||
if (_self) {
|
||||
_blocks.push_back(new ChatSettingsWidget(this, _self));
|
||||
_blocks.push_back(new BackgroundWidget(this, _self));
|
||||
_blocks.push_back(new PrivacyWidget(this, _self));
|
||||
_blocks->add(object_ptr<ChatSettingsWidget>(this, _self));
|
||||
_blocks->add(object_ptr<BackgroundWidget>(this, _self));
|
||||
_blocks->add(object_ptr<PrivacyWidget>(this, _self));
|
||||
}
|
||||
_blocks.push_back(new AdvancedWidget(this, _self));
|
||||
_blocks->add(object_ptr<AdvancedWidget>(this, _self));
|
||||
|
||||
if (_cover) {
|
||||
_cover->show();
|
||||
|
@ -90,10 +81,12 @@ void InnerWidget::refreshBlocks() {
|
|||
_cover->showFinished();
|
||||
}
|
||||
}
|
||||
for_const (auto block, _blocks) {
|
||||
block->show();
|
||||
connect(block, SIGNAL(heightUpdated()), this, SLOT(onBlockHeightUpdated()));
|
||||
}
|
||||
_blocks->show();
|
||||
_blocks->heightValue()
|
||||
| rpl::on_next([this](int blocksHeight) {
|
||||
resize(width(), _blocks->y() + blocksHeight);
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void InnerWidget::showFinished() {
|
||||
|
@ -108,44 +101,25 @@ int InnerWidget::resizeGetHeight(int newWidth) {
|
|||
_cover->setContentLeft(_contentLeft);
|
||||
_cover->resizeToWidth(newWidth);
|
||||
}
|
||||
for_const (auto block, _blocks) {
|
||||
block->setContentLeft(_contentLeft);
|
||||
block->resizeToWidth(newWidth);
|
||||
}
|
||||
|
||||
int result = refreshBlocksPositions(newWidth);
|
||||
return result;
|
||||
_blocks->resizeToWidth(newWidth - 2 * _contentLeft);
|
||||
_blocks->moveToLeft(
|
||||
_contentLeft,
|
||||
(_cover ? (_cover->y() + _cover->height()) : 0)
|
||||
+ st::settingsBlocksTop);
|
||||
return height();
|
||||
}
|
||||
|
||||
int InnerWidget::refreshBlocksPositions(int newWidth) {
|
||||
int result = (_cover ? _cover->height() : 0) + st::settingsBlocksTop;
|
||||
for_const (auto block, _blocks) {
|
||||
if (block->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
block->moveToLeft(0, result, newWidth);
|
||||
result += block->height();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void InnerWidget::onBlockHeightUpdated() {
|
||||
int newHeight = refreshBlocksPositions(width());
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
emit heightUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
for_const (auto block, _blocks) {
|
||||
int blockY = block->y();
|
||||
block->setVisibleTopBottom(visibleTop - blockY, visibleBottom - blockY);
|
||||
}
|
||||
void InnerWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
setChildVisibleTopBottom(
|
||||
_cover,
|
||||
visibleTop,
|
||||
visibleBottom);
|
||||
setChildVisibleTopBottom(
|
||||
_blocks,
|
||||
visibleTop,
|
||||
visibleBottom);
|
||||
}
|
||||
|
||||
} // namespace Settings
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "settings/settings_layer.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
|
@ -28,8 +29,6 @@ class CoverWidget;
|
|||
class BlockWidget;
|
||||
|
||||
class InnerWidget : public LayerInner, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InnerWidget(QWidget *parent);
|
||||
|
||||
|
@ -39,36 +38,26 @@ public:
|
|||
return TWidget::resizeToWidth(newWidth);
|
||||
}
|
||||
|
||||
// Updates the area that is visible inside the scroll container.
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||
|
||||
void showFinished();
|
||||
|
||||
private slots:
|
||||
void onBlockHeightUpdated();
|
||||
|
||||
protected:
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) override;
|
||||
|
||||
private:
|
||||
void fullRebuild();
|
||||
void refreshBlocks();
|
||||
|
||||
// Returns the new height value.
|
||||
int refreshBlocksPositions(int newWidth);
|
||||
|
||||
object_ptr<CoverWidget> _cover = { nullptr };
|
||||
QList<BlockWidget*> _blocks;
|
||||
object_ptr<Ui::VerticalLayout> _blocks;
|
||||
|
||||
UserData *_self = nullptr;
|
||||
|
||||
int _contentLeft = 0;
|
||||
bool _showFinished = false;
|
||||
|
||||
int _visibleTop = 0;
|
||||
int _visibleBottom = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Settings
|
||||
|
|
|
@ -50,21 +50,19 @@ Layer::Layer()
|
|||
_fixedBarShadow->hideFast();
|
||||
_scroll->moveToLeft(0, st::settingsFixedBarHeight);
|
||||
|
||||
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||
_scroll->scrollTopValue()
|
||||
| rpl::map([](int scrollTop) { return scrollTop > 0; })
|
||||
| rpl::distinct_until_changed()
|
||||
| rpl::on_next([this](bool scrolled) {
|
||||
_fixedBarShadow->toggleAnimated(scrolled);
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void Layer::setCloseClickHandler(base::lambda<void()> callback) {
|
||||
_fixedBarClose->setClickedCallback(std::move(callback));
|
||||
}
|
||||
|
||||
void Layer::onScroll() {
|
||||
if (_scroll->scrollTop() > 0) {
|
||||
_fixedBarShadow->showAnimated();
|
||||
} else {
|
||||
_fixedBarShadow->hideAnimated();
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::resizeToWidth(int newWidth, int newContentLeft) {
|
||||
// Widget height depends on InnerWidget height, so we
|
||||
// resize it here, not in the resizeEvent() handler.
|
||||
|
@ -73,13 +71,13 @@ void Layer::resizeToWidth(int newWidth, int newContentLeft) {
|
|||
resizeUsingInnerHeight(newWidth, _inner->height());
|
||||
}
|
||||
|
||||
void Layer::onInnerHeightUpdated() {
|
||||
resizeUsingInnerHeight(width(), _inner->height());
|
||||
}
|
||||
|
||||
void Layer::doSetInnerWidget(object_ptr<LayerInner> widget) {
|
||||
_inner = _scroll->setOwnedWidget(std::move(widget));
|
||||
connect(_inner, SIGNAL(heightUpdated()), this, SLOT(onInnerHeightUpdated()));
|
||||
_inner->heightValue()
|
||||
| rpl::on_next([this](int innerHeight) {
|
||||
resizeUsingInnerHeight(width(), innerHeight);
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void Layer::paintEvent(QPaintEvent *e) {
|
||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "layerwidget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class BoxLayerTitleShadow;
|
||||
|
||||
|
@ -34,9 +35,9 @@ class WidgetFadeWrap;
|
|||
namespace Settings {
|
||||
|
||||
class FixedBar;
|
||||
class LayerInner : public TWidget {
|
||||
class LayerInner : public Ui::RpWidget {
|
||||
public:
|
||||
LayerInner(QWidget *parent) : TWidget(parent) {
|
||||
LayerInner(QWidget *parent) : RpWidget(parent) {
|
||||
}
|
||||
|
||||
virtual void resizeToWidth(int newWidth, int contentLeft) {
|
||||
|
@ -46,8 +47,6 @@ public:
|
|||
};
|
||||
|
||||
class Layer : public LayerWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Layer();
|
||||
|
||||
|
@ -70,10 +69,6 @@ protected:
|
|||
_roundedCorners = roundedCorners;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onInnerHeightUpdated();
|
||||
void onScroll();
|
||||
|
||||
private:
|
||||
void doSetInnerWidget(object_ptr<LayerInner> widget);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "styles/style_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "mainwindow.h"
|
||||
|
@ -56,9 +56,9 @@ NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : Bloc
|
|||
void NotificationsWidget::createControls() {
|
||||
style::margins margin(0, 0, 0, st::settingsSkip);
|
||||
style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2));
|
||||
addChildRow(_desktopNotifications, margin, lang(lng_settings_desktop_notify), [this](bool) { onDesktopNotifications(); }, Global::DesktopNotify());
|
||||
addChildRow(_showSenderName, margin, slidedPadding, lang(lng_settings_show_name), [this](bool) { onShowSenderName(); }, Global::NotifyView() <= dbinvShowName);
|
||||
addChildRow(_showMessagePreview, margin, slidedPadding, lang(lng_settings_show_preview), [this](bool) { onShowMessagePreview(); }, Global::NotifyView() <= dbinvShowPreview);
|
||||
createChildRow(_desktopNotifications, margin, lang(lng_settings_desktop_notify), [this](bool) { onDesktopNotifications(); }, Global::DesktopNotify());
|
||||
createChildRow(_showSenderName, margin, slidedPadding, lang(lng_settings_show_name), [this](bool) { onShowSenderName(); }, Global::NotifyView() <= dbinvShowName);
|
||||
createChildRow(_showMessagePreview, margin, slidedPadding, lang(lng_settings_show_preview), [this](bool) { onShowMessagePreview(); }, Global::NotifyView() <= dbinvShowPreview);
|
||||
if (!_showSenderName->entity()->checked()) {
|
||||
_showMessagePreview->hideFast();
|
||||
}
|
||||
|
@ -66,8 +66,8 @@ void NotificationsWidget::createControls() {
|
|||
_showSenderName->hideFast();
|
||||
_showMessagePreview->hideFast();
|
||||
}
|
||||
addChildRow(_playSound, margin, lang(lng_settings_sound_notify), [this](bool) { onPlaySound(); }, Global::SoundNotify());
|
||||
addChildRow(_includeMuted, margin, lang(lng_settings_include_muted), [this](bool) { onIncludeMuted(); }, Global::IncludeMuted());
|
||||
createChildRow(_playSound, margin, lang(lng_settings_sound_notify), [this](bool) { onPlaySound(); }, Global::SoundNotify());
|
||||
createChildRow(_includeMuted, margin, lang(lng_settings_include_muted), [this](bool) { onIncludeMuted(); }, Global::IncludeMuted());
|
||||
|
||||
if (cPlatform() != dbipMac) {
|
||||
createNotificationsControls();
|
||||
|
@ -87,9 +87,9 @@ void NotificationsWidget::createNotificationsControls() {
|
|||
#endif // Q_OS_WIN || Q_OS_LINUX64 || Q_OS_LINUX32
|
||||
}
|
||||
if (!nativeNotificationsLabel.isEmpty()) {
|
||||
addChildRow(_nativeNotifications, margin, nativeNotificationsLabel, [this](bool) { onNativeNotifications(); }, Global::NativeNotifications());
|
||||
createChildRow(_nativeNotifications, margin, nativeNotificationsLabel, [this](bool) { onNativeNotifications(); }, Global::NativeNotifications());
|
||||
}
|
||||
addChildRow(_advanced, margin, slidedPadding, lang(lng_settings_advanced_notifications), SLOT(onAdvanced()));
|
||||
createChildRow(_advanced, margin, slidedPadding, lang(lng_settings_advanced_notifications), SLOT(onAdvanced()));
|
||||
if (!nativeNotificationsLabel.isEmpty() && Global::NativeNotifications()) {
|
||||
_advanced->hideFast();
|
||||
}
|
||||
|
|
|
@ -45,13 +45,13 @@ private:
|
|||
void desktopEnabledUpdated();
|
||||
void viewParamUpdated();
|
||||
|
||||
object_ptr<Ui::Checkbox> _desktopNotifications = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::Checkbox>> _showSenderName = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::Checkbox>> _showMessagePreview = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _nativeNotifications = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _playSound = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _includeMuted = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _advanced = { nullptr };
|
||||
Ui::Checkbox *_desktopNotifications = nullptr;
|
||||
Ui::SlideWrap<Ui::Checkbox> *_showSenderName = nullptr;
|
||||
Ui::SlideWrap<Ui::Checkbox> *_showMessagePreview = nullptr;
|
||||
Ui::Checkbox *_nativeNotifications = nullptr;
|
||||
Ui::Checkbox *_playSound = nullptr;
|
||||
Ui::Checkbox *_includeMuted = nullptr;
|
||||
Ui::SlideWrap<Ui::LinkButton> *_advanced = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#include "settings/settings_privacy_widget.h"
|
||||
|
||||
#include "ui/effects/widget_slide_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
@ -36,7 +36,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Settings {
|
||||
|
||||
LocalPasscodeState::LocalPasscodeState(QWidget *parent) : TWidget(parent)
|
||||
LocalPasscodeState::LocalPasscodeState(QWidget *parent) : RpWidget(parent)
|
||||
, _edit(this, GetEditPasscodeText(), st::boxLinkButton)
|
||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
||||
updateControls();
|
||||
|
@ -69,7 +69,7 @@ QString LocalPasscodeState::GetEditPasscodeText() {
|
|||
return lang(Global::LocalPasscode() ? lng_passcode_change : lng_passcode_turn_on);
|
||||
}
|
||||
|
||||
CloudPasswordState::CloudPasswordState(QWidget *parent) : TWidget(parent)
|
||||
CloudPasswordState::CloudPasswordState(QWidget *parent) : RpWidget(parent)
|
||||
, _edit(this, lang(lng_cloud_password_set), st::boxLinkButton)
|
||||
, _turnOff(this, lang(lng_passcode_turn_off), st::boxLinkButton) {
|
||||
_turnOff->hide();
|
||||
|
@ -182,20 +182,20 @@ void PrivacyWidget::createControls() {
|
|||
style::margins marginSkip(0, 0, 0, st::settingsSkip);
|
||||
style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2));
|
||||
|
||||
addChildRow(_blockedUsers, marginSmall, lang(lng_settings_blocked_users), SLOT(onBlockedUsers()));
|
||||
addChildRow(_lastSeenPrivacy, marginSmall, lang(lng_settings_last_seen_privacy), SLOT(onLastSeenPrivacy()));
|
||||
addChildRow(_callsPrivacy, marginSmall, lang(lng_settings_calls_privacy), SLOT(onCallsPrivacy()));
|
||||
addChildRow(_groupsInvitePrivacy, marginSmall, lang(lng_settings_groups_invite_privacy), SLOT(onGroupsInvitePrivacy()));
|
||||
addChildRow(_localPasscodeState, marginSmall);
|
||||
createChildRow(_blockedUsers, marginSmall, lang(lng_settings_blocked_users), SLOT(onBlockedUsers()));
|
||||
createChildRow(_lastSeenPrivacy, marginSmall, lang(lng_settings_last_seen_privacy), SLOT(onLastSeenPrivacy()));
|
||||
createChildRow(_callsPrivacy, marginSmall, lang(lng_settings_calls_privacy), SLOT(onCallsPrivacy()));
|
||||
createChildRow(_groupsInvitePrivacy, marginSmall, lang(lng_settings_groups_invite_privacy), SLOT(onGroupsInvitePrivacy()));
|
||||
createChildRow(_localPasscodeState, marginSmall);
|
||||
auto label = lang(psIdleSupported() ? lng_passcode_autolock_away : lng_passcode_autolock_inactive);
|
||||
auto value = GetAutoLockText();
|
||||
addChildRow(_autoLock, marginSmall, slidedPadding, label, value, LabeledLink::Type::Primary, SLOT(onAutoLock()));
|
||||
createChildRow(_autoLock, marginSmall, slidedPadding, label, value, LabeledLink::Type::Primary, SLOT(onAutoLock()));
|
||||
if (!Global::LocalPasscode()) {
|
||||
_autoLock->hideFast();
|
||||
}
|
||||
addChildRow(_cloudPasswordState, marginSmall);
|
||||
addChildRow(_showAllSessions, marginSmall, lang(lng_settings_show_sessions), SLOT(onShowSessions()));
|
||||
addChildRow(_selfDestruction, marginSmall, lang(lng_settings_self_destruct), SLOT(onSelfDestruction()));
|
||||
createChildRow(_cloudPasswordState, marginSmall);
|
||||
createChildRow(_showAllSessions, marginSmall, lang(lng_settings_show_sessions), SLOT(onShowSessions()));
|
||||
createChildRow(_selfDestruction, marginSmall, lang(lng_settings_self_destruct), SLOT(onSelfDestruction()));
|
||||
}
|
||||
|
||||
void PrivacyWidget::autoLockUpdated() {
|
||||
|
|
|
@ -22,10 +22,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "settings/settings_block_widget.h"
|
||||
#include "settings/settings_chat_settings_widget.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Settings {
|
||||
|
||||
class LocalPasscodeState : public TWidget, private base::Subscriber {
|
||||
class LocalPasscodeState : public Ui::RpWidget, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -48,7 +49,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class CloudPasswordState : public TWidget, private base::Subscriber, public RPCSender {
|
||||
class CloudPasswordState : public Ui::RpWidget, private base::Subscriber, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -101,15 +102,15 @@ private:
|
|||
void createControls();
|
||||
void autoLockUpdated();
|
||||
|
||||
object_ptr<Ui::LinkButton> _blockedUsers = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _lastSeenPrivacy = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _callsPrivacy = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _groupsInvitePrivacy = { nullptr };
|
||||
object_ptr<LocalPasscodeState> _localPasscodeState = { nullptr };
|
||||
object_ptr<Ui::WidgetSlideWrap<LabeledLink>> _autoLock = { nullptr };
|
||||
object_ptr<CloudPasswordState> _cloudPasswordState = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _showAllSessions = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _selfDestruction = { nullptr };
|
||||
Ui::LinkButton *_blockedUsers = nullptr;
|
||||
Ui::LinkButton *_lastSeenPrivacy = nullptr;
|
||||
Ui::LinkButton *_callsPrivacy = nullptr;
|
||||
Ui::LinkButton *_groupsInvitePrivacy = nullptr;
|
||||
LocalPasscodeState *_localPasscodeState = nullptr;
|
||||
Ui::SlideWrap<LabeledLink> *_autoLock = nullptr;
|
||||
CloudPasswordState *_cloudPasswordState = nullptr;
|
||||
Ui::LinkButton *_showAllSessions = nullptr;
|
||||
Ui::LinkButton *_selfDestruction = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -52,15 +52,17 @@ ScaleWidget::ScaleWidget(QWidget *parent, UserData *self) : BlockWidget(parent,
|
|||
void ScaleWidget::createControls() {
|
||||
style::margins margin(0, 0, 0, st::settingsSmallSkip);
|
||||
|
||||
addChildRow(_auto, margin, lng_settings_scale_auto(lt_cur, scaleLabel(cScreenScale())), [this](bool) { onAutoChanged(); }, (cConfigScale() == dbisAuto));
|
||||
addChildRow(_scale, style::margins(0, 0, 0, 0));
|
||||
createChildRow(_auto, margin, lng_settings_scale_auto(lt_cur, scaleLabel(cScreenScale())), [this](bool) { onAutoChanged(); }, (cConfigScale() == dbisAuto));
|
||||
createChildRow(_scale, style::margins(0, 0, 0, 0));
|
||||
|
||||
_scale->addSection(scaleLabel(dbisOne));
|
||||
_scale->addSection(scaleLabel(dbisOneAndQuarter));
|
||||
_scale->addSection(scaleLabel(dbisOneAndHalf));
|
||||
_scale->addSection(scaleLabel(dbisTwo));
|
||||
_scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
|
||||
_scale->setSectionActivatedCallback([this] { scaleChanged(); });
|
||||
_scale->sectionActivated()
|
||||
| rpl::on_next([this](int) { scaleChanged(); })
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
|
||||
void ScaleWidget::onAutoChanged() {
|
||||
|
|
|
@ -43,8 +43,8 @@ private:
|
|||
void createControls();
|
||||
void setScale(DBIScale newScale);
|
||||
|
||||
object_ptr<Ui::Checkbox> _auto = { nullptr };
|
||||
object_ptr<Ui::SettingsSlider> _scale = { nullptr };
|
||||
Ui::Checkbox *_auto = nullptr;
|
||||
Ui::SettingsSlider *_scale = nullptr;
|
||||
|
||||
DBIScale _newScale = dbisAuto;
|
||||
bool _inSetScale = false;
|
||||
|
|
|
@ -245,7 +245,7 @@ void Widget::parentResized() {
|
|||
}
|
||||
|
||||
void Widget::resizeUsingInnerHeight(int newWidth, int innerHeight) {
|
||||
if (!App::wnd()) return;
|
||||
if (!parentWidget()) return;
|
||||
|
||||
auto parentSize = parentWidget()->size();
|
||||
auto windowWidth = parentSize.width();
|
||||
|
|
|
@ -27,8 +27,6 @@ namespace Settings {
|
|||
class InnerWidget;
|
||||
|
||||
class Widget : public Layer, private base::Subscriber {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Widget(QWidget*);
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/producer.h>
|
||||
#include "base/enum_mask.h"
|
||||
#include "rpl/producer.h"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "storage/storage_facade.h"
|
||||
#include "rpl/event_stream.h"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "storage/storage_facade.h"
|
||||
#include "rpl/event_stream.h"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
|
|||
onStateChanged(was, StateChangeSource::ByPress);
|
||||
if (was & StateFlag::Over) {
|
||||
_modifiers = e->modifiers();
|
||||
_clicks.fire({});
|
||||
if (_clickedCallback) {
|
||||
_clickedCallback();
|
||||
} else {
|
||||
|
|
|
@ -20,16 +20,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/twidget.h"
|
||||
#include <rpl/event_stream.h>
|
||||
#include "ui/rp_widget.h"
|
||||
#include "base/flags.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class AbstractButton : public TWidget {
|
||||
class AbstractButton : public RpWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AbstractButton(QWidget *parent) : TWidget(parent) {
|
||||
AbstractButton(QWidget *parent) : RpWidget(parent) {
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
|
@ -64,6 +65,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
rpl::producer<> clicks() const {
|
||||
return _clicks.events();
|
||||
}
|
||||
|
||||
protected:
|
||||
void enterEventHook(QEvent *e) override;
|
||||
void leaveEventHook(QEvent *e) override;
|
||||
|
@ -109,6 +114,8 @@ private:
|
|||
|
||||
base::lambda<void()> _clickedCallback;
|
||||
|
||||
rpl::event_stream<> _clicks;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -22,115 +22,159 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Ui {
|
||||
|
||||
WidgetSlideWrap<TWidget>::WidgetSlideWrap(QWidget *parent
|
||||
, object_ptr<TWidget> entity
|
||||
, style::margins entityPadding
|
||||
, base::lambda<void()> updateCallback
|
||||
, int duration) : TWidget(parent)
|
||||
, _entity(std::move(entity))
|
||||
, _padding(entityPadding)
|
||||
, _duration(duration)
|
||||
, _updateCallback(std::move(updateCallback)) {
|
||||
_entity->setParent(this);
|
||||
auto margins = getMargins();
|
||||
_entity->moveToLeft(margins.left() + _padding.left(), margins.top() + _padding.top());
|
||||
_realSize = _entity->rectNoMargins().marginsAdded(_padding).size();
|
||||
_entity->installEventFilter(this);
|
||||
resizeToWidth(_realSize.width());
|
||||
}
|
||||
|
||||
void WidgetSlideWrap<TWidget>::hideAnimated() {
|
||||
if (isHidden()) {
|
||||
_forceHeight = 0;
|
||||
resizeToWidth(_realSize.width());
|
||||
if (_updateCallback) _updateCallback();
|
||||
return;
|
||||
}
|
||||
if (_a_height.animating()) {
|
||||
if (_hiding) return;
|
||||
}
|
||||
_hiding = true;
|
||||
_a_height.start([this] { animationCallback(); }, _realSize.height(), 0., _duration);
|
||||
}
|
||||
|
||||
void WidgetSlideWrap<TWidget>::showAnimated() {
|
||||
if (isHidden()) {
|
||||
show();
|
||||
}
|
||||
if (_forceHeight < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_a_height.animating()) {
|
||||
if (!_hiding) return;
|
||||
}
|
||||
_hiding = false;
|
||||
_forceHeight = qRound(_a_height.current(0.));
|
||||
_a_height.start([this] { animationCallback(); }, 0., _realSize.height(), _duration);
|
||||
}
|
||||
|
||||
void WidgetSlideWrap<TWidget>::toggleFast(bool visible) {
|
||||
_hiding = !visible;
|
||||
if (!_hiding) show();
|
||||
_a_height.finish();
|
||||
_forceHeight = _hiding ? 0 : -1;
|
||||
resizeToWidth(_realSize.width());
|
||||
if (_hiding) hide();
|
||||
if (_updateCallback) {
|
||||
_updateCallback();
|
||||
PaddingWrap<RpWidget>::PaddingWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding)
|
||||
: Parent(parent, std::move(child))
|
||||
, _padding(padding) {
|
||||
if (auto weak = wrapped()) {
|
||||
auto margins = weak->getMargins();
|
||||
weak->sizeValue()
|
||||
| rpl::on_next([this](QSize&&) { updateSize(); })
|
||||
| rpl::start(lifetime());
|
||||
weak->moveToLeft(_padding.left() + margins.left(), _padding.top() + margins.top());
|
||||
}
|
||||
}
|
||||
|
||||
QMargins WidgetSlideWrap<TWidget>::getMargins() const {
|
||||
auto entityMargins = _entity->getMargins();
|
||||
if (_forceHeight < 0) {
|
||||
return entityMargins;
|
||||
}
|
||||
return QMargins(entityMargins.left(), 0, entityMargins.right(), 0);
|
||||
}
|
||||
|
||||
int WidgetSlideWrap<TWidget>::naturalWidth() const {
|
||||
auto inner = _entity->naturalWidth();
|
||||
return (inner < 0) ? inner : (_padding.left() + inner + _padding.right());
|
||||
}
|
||||
|
||||
bool WidgetSlideWrap<TWidget>::eventFilter(QObject *object, QEvent *event) {
|
||||
if (object == _entity && event->type() == QEvent::Resize) {
|
||||
_realSize = _entity->rectNoMargins().marginsAdded(_padding).size();
|
||||
if (!_inResizeToWidth) {
|
||||
resizeToWidth(_realSize.width());
|
||||
if (_updateCallback) {
|
||||
_updateCallback();
|
||||
}
|
||||
void PaddingWrap<RpWidget>::updateSize() {
|
||||
auto inner = [this] {
|
||||
if (auto weak = wrapped()) {
|
||||
return weak->rect();
|
||||
}
|
||||
}
|
||||
return TWidget::eventFilter(object, event);
|
||||
return QRect(0, 0, _innerWidth, 0);
|
||||
}();
|
||||
resize(inner.marginsAdded(_padding).size());
|
||||
}
|
||||
|
||||
int WidgetSlideWrap<TWidget>::resizeGetHeight(int newWidth) {
|
||||
_inResizeToWidth = true;
|
||||
auto resized = (_forceHeight >= 0);
|
||||
_entity->resizeToWidth(newWidth - _padding.left() - _padding.right());
|
||||
auto margins = getMargins();
|
||||
_entity->moveToLeft(margins.left() + _padding.left(), margins.top() + _padding.top());
|
||||
_inResizeToWidth = false;
|
||||
if (resized) {
|
||||
return _forceHeight;
|
||||
}
|
||||
_realSize = _entity->rectNoMargins().marginsAdded(_padding).size();
|
||||
return _realSize.height();
|
||||
int PaddingWrap<RpWidget>::naturalWidth() const {
|
||||
auto inner = [this] {
|
||||
if (auto weak = wrapped()) {
|
||||
return weak->naturalWidth();
|
||||
}
|
||||
return RpWidget::naturalWidth();
|
||||
}();
|
||||
return (inner < 0)
|
||||
? inner
|
||||
: (_padding.left() + inner + _padding.right());
|
||||
}
|
||||
|
||||
void WidgetSlideWrap<TWidget>::animationCallback() {
|
||||
_forceHeight = qRound(_a_height.current(_hiding ? 0 : -1));
|
||||
resizeToWidth(_realSize.width());
|
||||
if (!_a_height.animating()) {
|
||||
_forceHeight = _hiding ? 0 : -1;
|
||||
if (_hiding) hide();
|
||||
int PaddingWrap<RpWidget>::resizeGetHeight(int newWidth) {
|
||||
_innerWidth = newWidth;
|
||||
if (auto weak = wrapped()) {
|
||||
weak->resizeToWidth(newWidth
|
||||
- _padding.left()
|
||||
- _padding.right());
|
||||
} else {
|
||||
updateSize();
|
||||
}
|
||||
if (_updateCallback) {
|
||||
_updateCallback();
|
||||
return height();
|
||||
}
|
||||
|
||||
SlideWrap<RpWidget>::SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child)
|
||||
: SlideWrap(
|
||||
parent,
|
||||
std::move(child),
|
||||
style::margins(),
|
||||
st::slideWrapDuration) {
|
||||
}
|
||||
|
||||
SlideWrap<RpWidget>::SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding)
|
||||
: SlideWrap(
|
||||
parent,
|
||||
std::move(child),
|
||||
padding,
|
||||
st::slideWrapDuration) {
|
||||
}
|
||||
|
||||
SlideWrap<RpWidget>::SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
int duration)
|
||||
: SlideWrap(parent, std::move(child), style::margins(), duration) {
|
||||
}
|
||||
|
||||
SlideWrap<RpWidget>::SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding,
|
||||
int duration)
|
||||
: Parent(parent, object_ptr<PaddingWrap<RpWidget>>(parent, std::move(child), padding))
|
||||
, _duration(duration * 10) {
|
||||
if (auto weak = wrapped()) {
|
||||
weak->heightValue()
|
||||
| rpl::on_next([this](int newHeight) {
|
||||
if (_slideAnimation.animating()) {
|
||||
animationStep();
|
||||
} else if (_visible) {
|
||||
resize(width(), newHeight);
|
||||
}
|
||||
}) | rpl::start(lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
void SlideWrap<RpWidget>::animationStep() {
|
||||
if (wrapped()) {
|
||||
auto margins = getMargins();
|
||||
wrapped()->moveToLeft(margins.left(), margins.top());
|
||||
}
|
||||
auto current = _slideAnimation.current(_visible ? 1. : 0.);
|
||||
auto newHeight = wrapped()
|
||||
? (_slideAnimation.animating()
|
||||
? anim::interpolate(0, wrapped()->heightNoMargins(), current)
|
||||
: (_visible ? wrapped()->height() : 0))
|
||||
: 0;
|
||||
if (newHeight != height()) {
|
||||
resize(width(), newHeight);
|
||||
}
|
||||
auto shouldBeHidden = !_visible && !_slideAnimation.animating();
|
||||
if (shouldBeHidden != isHidden()) {
|
||||
setVisible(!shouldBeHidden);
|
||||
}
|
||||
}
|
||||
|
||||
void SlideWrap<RpWidget>::toggleAnimated(bool visible) {
|
||||
if (_visible == visible) {
|
||||
animationStep();
|
||||
return;
|
||||
}
|
||||
_visible = visible;
|
||||
_slideAnimation.start(
|
||||
[this] { animationStep(); },
|
||||
_visible ? 0. : 1.,
|
||||
_visible ? 1. : 0.,
|
||||
_duration,
|
||||
anim::linear);
|
||||
animationStep();
|
||||
}
|
||||
|
||||
void SlideWrap<RpWidget>::toggleFast(bool visible) {
|
||||
_visible = visible;
|
||||
finishAnimations();
|
||||
}
|
||||
|
||||
void SlideWrap<RpWidget>::finishAnimations() {
|
||||
_slideAnimation.finish();
|
||||
animationStep();
|
||||
}
|
||||
|
||||
QMargins SlideWrap<RpWidget>::getMargins() const {
|
||||
auto result = wrapped()->getMargins();
|
||||
return (animating() || !_visible)
|
||||
? QMargins(result.left(), 0, result.right(), 0)
|
||||
: result;
|
||||
}
|
||||
|
||||
int SlideWrap<RpWidget>::resizeGetHeight(int newWidth) {
|
||||
if (wrapped()) {
|
||||
wrapped()->resizeToWidth(newWidth);
|
||||
}
|
||||
return height();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -21,100 +21,263 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
template <typename Widget, typename ParentType = RpWidget>
|
||||
class Wrap;
|
||||
|
||||
namespace details {
|
||||
|
||||
struct UnwrapHelper {
|
||||
struct Large {
|
||||
char data[2];
|
||||
};
|
||||
static char Check(...);
|
||||
template <typename Widget, typename Parent>
|
||||
static Large Check(Wrap<Widget, Parent>*);
|
||||
template <typename Widget, typename Parent>
|
||||
static Large Check(const Wrap<Widget, Parent>*);
|
||||
|
||||
template <typename Entity>
|
||||
static constexpr bool Is() {
|
||||
return sizeof(Check(std::declval<Entity>()))
|
||||
== sizeof(Large);
|
||||
}
|
||||
template <typename Entity>
|
||||
static auto Unwrap(Entity *entity, std::true_type) {
|
||||
return entity
|
||||
? entity->entity()
|
||||
: nullptr;
|
||||
}
|
||||
template <typename Entity>
|
||||
static Entity *Unwrap(Entity *entity, std::false_type) {
|
||||
return entity;
|
||||
}
|
||||
template <typename Entity>
|
||||
static auto Unwrap(Entity *entity) {
|
||||
return Unwrap(
|
||||
entity,
|
||||
std::integral_constant<bool, Is<Entity*>()>());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap;
|
||||
class Wrap<Widget, RpWidget> : public RpWidget {
|
||||
public:
|
||||
Wrap(QWidget *parent, object_ptr<Widget> child);
|
||||
|
||||
Widget *wrapped() {
|
||||
return _wrapped;
|
||||
}
|
||||
const Widget *wrapped() const {
|
||||
return _wrapped;
|
||||
}
|
||||
auto entity() {
|
||||
return details::UnwrapHelper::Unwrap(wrapped());
|
||||
}
|
||||
auto entity() const {
|
||||
return details::UnwrapHelper::Unwrap(wrapped());
|
||||
}
|
||||
|
||||
QMargins getMargins() const override {
|
||||
if (auto weak = wrapped()) {
|
||||
return weak->getMargins();
|
||||
}
|
||||
return RpWidget::getMargins();
|
||||
}
|
||||
int naturalWidth() const override {
|
||||
if (auto weak = wrapped()) {
|
||||
return weak->naturalWidth();
|
||||
}
|
||||
return RpWidget::naturalWidth();
|
||||
}
|
||||
|
||||
private:
|
||||
object_ptr<Widget> _wrapped;
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
Wrap<Widget, RpWidget>::Wrap(QWidget *parent, object_ptr<Widget> child)
|
||||
: RpWidget(parent)
|
||||
, _wrapped(std::move(child)) {
|
||||
if (_wrapped) {
|
||||
resize(_wrapped->size());
|
||||
AttachParentChild(this, _wrapped);
|
||||
_wrapped->move(0, 0);
|
||||
_wrapped->alive()
|
||||
| rpl::on_done([this] {
|
||||
_wrapped->setParent(nullptr);
|
||||
_wrapped = nullptr;
|
||||
delete this;
|
||||
})
|
||||
| rpl::start(lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Widget, typename ParentType>
|
||||
class Wrap : public ParentType {
|
||||
public:
|
||||
using ParentType::ParentType;
|
||||
|
||||
Widget *wrapped() {
|
||||
return static_cast<Widget*>(ParentType::wrapped());
|
||||
}
|
||||
const Widget *wrapped() const {
|
||||
return static_cast<const Widget*>(ParentType::wrapped());
|
||||
}
|
||||
auto entity() {
|
||||
return details::UnwrapHelper::Unwrap(wrapped());
|
||||
}
|
||||
auto entity() const {
|
||||
return details::UnwrapHelper::Unwrap(wrapped());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
class PaddingWrap;
|
||||
|
||||
template <>
|
||||
class WidgetSlideWrap<TWidget> : public TWidget {
|
||||
public:
|
||||
WidgetSlideWrap(QWidget *parent
|
||||
, object_ptr<TWidget> entity
|
||||
, style::margins entityPadding
|
||||
, base::lambda<void()> updateCallback
|
||||
, int duration = st::widgetSlideDuration);
|
||||
class PaddingWrap<RpWidget> : public Wrap<RpWidget> {
|
||||
using Parent = Wrap<RpWidget>;
|
||||
|
||||
void showAnimated();
|
||||
void hideAnimated();
|
||||
void toggleAnimated(bool visible) {
|
||||
if (visible) {
|
||||
showAnimated();
|
||||
} else {
|
||||
hideAnimated();
|
||||
}
|
||||
public:
|
||||
PaddingWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding);
|
||||
|
||||
PaddingWrap(
|
||||
QWidget *parent,
|
||||
const style::margins &padding)
|
||||
: PaddingWrap(parent, nullptr, padding) {
|
||||
}
|
||||
|
||||
int naturalWidth() const override;
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void updateSize();
|
||||
|
||||
int _innerWidth = 0;
|
||||
style::margins _padding;
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
class PaddingWrap : public Wrap<Widget, PaddingWrap<RpWidget>> {
|
||||
using Parent = Wrap<Widget, PaddingWrap<RpWidget>>;
|
||||
|
||||
public:
|
||||
PaddingWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<Widget> child,
|
||||
const style::margins &padding)
|
||||
: Parent(parent, std::move(child), padding) {
|
||||
}
|
||||
|
||||
PaddingWrap(QWidget *parent, const style::margins &padding)
|
||||
: Parent(parent, padding) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
|
||||
template <>
|
||||
class SlideWrap<RpWidget> : public Wrap<PaddingWrap<RpWidget>> {
|
||||
using Parent = Wrap<PaddingWrap<RpWidget>>;
|
||||
|
||||
public:
|
||||
SlideWrap(QWidget *parent, object_ptr<RpWidget> child);
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding);
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
int duration);
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<RpWidget> child,
|
||||
const style::margins &padding,
|
||||
int duration);
|
||||
|
||||
void toggleAnimated(bool visible);
|
||||
void toggleFast(bool visible);
|
||||
|
||||
void showAnimated() {
|
||||
toggleAnimated(true);
|
||||
}
|
||||
void hideAnimated() {
|
||||
toggleAnimated(false);
|
||||
}
|
||||
|
||||
void showFast() {
|
||||
toggleFast(true);
|
||||
}
|
||||
void hideFast() {
|
||||
toggleFast(false);
|
||||
}
|
||||
void toggleFast(bool visible);
|
||||
|
||||
bool isHiddenOrHiding() const {
|
||||
return isHidden() || (_a_height.animating() && _hiding);
|
||||
}
|
||||
|
||||
void finishAnimation() {
|
||||
_a_height.finish();
|
||||
myEnsureResized(_entity);
|
||||
animationCallback();
|
||||
}
|
||||
bool animating() const {
|
||||
return _a_height.animating();
|
||||
}
|
||||
|
||||
TWidget *entity() {
|
||||
return _entity;
|
||||
}
|
||||
|
||||
const TWidget *entity() const {
|
||||
return _entity;
|
||||
return _slideAnimation.animating();
|
||||
}
|
||||
void finishAnimations();
|
||||
|
||||
QMargins getMargins() const override;
|
||||
int naturalWidth() const override;
|
||||
|
||||
bool isHiddenOrHiding() const {
|
||||
return !_visible;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
private:
|
||||
void animationCallback();
|
||||
void animationStep();
|
||||
|
||||
object_ptr<TWidget> _entity;
|
||||
bool _inResizeToWidth = false;
|
||||
style::margins _padding;
|
||||
int _duration;
|
||||
base::lambda<void()> _updateCallback;
|
||||
|
||||
style::size _realSize;
|
||||
int _forceHeight = -1;
|
||||
Animation _a_height;
|
||||
bool _hiding = false;
|
||||
bool _visible = true;
|
||||
Animation _slideAnimation;
|
||||
int _duration = 0;
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
class WidgetSlideWrap : public WidgetSlideWrap<TWidget> {
|
||||
class SlideWrap : public Wrap<PaddingWrap<Widget>, SlideWrap<RpWidget>> {
|
||||
using Parent = Wrap<PaddingWrap<Widget>, SlideWrap<RpWidget>>;
|
||||
|
||||
public:
|
||||
WidgetSlideWrap(QWidget *parent
|
||||
, object_ptr<Widget> entity
|
||||
, style::margins entityPadding
|
||||
, base::lambda<void()> updateCallback
|
||||
, int duration = st::widgetSlideDuration) : WidgetSlideWrap<TWidget>(parent
|
||||
, std::move(entity)
|
||||
, entityPadding
|
||||
, std::move(updateCallback)
|
||||
, duration) {
|
||||
SlideWrap(QWidget *parent, object_ptr<Widget> child)
|
||||
: Parent(parent, std::move(child)) {
|
||||
}
|
||||
Widget *entity() {
|
||||
return static_cast<Widget*>(WidgetSlideWrap<TWidget>::entity());
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<Widget> child,
|
||||
const style::margins &padding)
|
||||
: Parent(parent, std::move(child), padding) {
|
||||
}
|
||||
const Widget *entity() const {
|
||||
return static_cast<const Widget*>(WidgetSlideWrap<TWidget>::entity());
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<Widget> child,
|
||||
int duration)
|
||||
: Parent(parent, std::move(child), duration) {
|
||||
}
|
||||
SlideWrap(
|
||||
QWidget *parent,
|
||||
object_ptr<Widget> child,
|
||||
const style::margins &padding,
|
||||
int duration)
|
||||
: Parent(parent, std::move(child), padding, duration) {
|
||||
}
|
||||
|
||||
};
|
||||
|
|
130
Telegram/SourceFiles/ui/rp_widget.h
Normal file
130
Telegram/SourceFiles/ui/rp_widget.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include <rpl/map.h>
|
||||
#include <rpl/distinct_until_changed.h>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class RpWidget : public TWidget {
|
||||
public:
|
||||
RpWidget::RpWidget(QWidget *parent = nullptr) : TWidget(parent) {
|
||||
setGeometry(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
rpl::producer<QRect> geometryValue() const {
|
||||
auto &stream = eventFilter().geometry;
|
||||
return stream.events_starting_with_copy(geometry());
|
||||
}
|
||||
rpl::producer<QSize> sizeValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.size(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
rpl::producer<int> heightValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.height(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
rpl::producer<int> widthValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.width(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
rpl::producer<QPoint> positionValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.topLeft(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
rpl::producer<int> leftValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.left(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
rpl::producer<int> topValue() const {
|
||||
return geometryValue()
|
||||
| rpl::map([](QRect &&value) { return value.top(); })
|
||||
| rpl::distinct_until_changed();
|
||||
}
|
||||
virtual rpl::producer<int> desiredHeightValue() const {
|
||||
return heightValue();
|
||||
}
|
||||
|
||||
rpl::producer<QRect> paintRequest() const {
|
||||
return eventFilter().paint.events();
|
||||
}
|
||||
|
||||
rpl::producer<> alive() const {
|
||||
return eventFilter().alive.events();
|
||||
}
|
||||
|
||||
rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
||||
private:
|
||||
class EventFilter : public QObject {
|
||||
public:
|
||||
EventFilter(RpWidget *parent) : QObject(parent) {
|
||||
parent->installEventFilter(this);
|
||||
}
|
||||
rpl::event_stream<QRect> geometry;
|
||||
rpl::event_stream<QRect> paint;
|
||||
rpl::event_stream<> alive;
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) {
|
||||
auto widget = static_cast<RpWidget*>(parent());
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::Move:
|
||||
case QEvent::Resize:
|
||||
geometry.fire_copy(widget->geometry());
|
||||
break;
|
||||
|
||||
case QEvent::Paint:
|
||||
paint.fire_copy(
|
||||
static_cast<QPaintEvent*>(event)->rect());
|
||||
break;
|
||||
}
|
||||
|
||||
return QObject::eventFilter(object, event);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EventFilter &eventFilter() const {
|
||||
if (!_eventFilter) {
|
||||
auto that = const_cast<RpWidget*>(this);
|
||||
that->_eventFilter = std::make_unique<EventFilter>(that);
|
||||
}
|
||||
return *_eventFilter;
|
||||
}
|
||||
|
||||
std::unique_ptr<EventFilter> _eventFilter;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -57,18 +57,6 @@ inline ChildWidget *AttachParentChild(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename ChildWidget>
|
||||
inline ChildWidget *AttachParentChildToBottom(
|
||||
not_null<QWidget*> parent,
|
||||
const object_ptr<ChildWidget> &child) {
|
||||
if (auto raw = AttachParentChild(parent, child)) {
|
||||
raw->resizeToWidth(parent->width());
|
||||
raw->move(0, parent->height());
|
||||
return raw;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
enum class RectPart {
|
||||
|
@ -288,7 +276,7 @@ public:
|
|||
QRect mapFromGlobal(const QRect &rect) const {
|
||||
return QRect(mapFromGlobal(rect.topLeft()), rect.size());
|
||||
}
|
||||
QRect mapToGlobal(const QRect &rect) {
|
||||
QRect mapToGlobal(const QRect &rect) const {
|
||||
return QRect(mapToGlobal(rect.topLeft()), rect.size());
|
||||
}
|
||||
|
||||
|
@ -410,7 +398,11 @@ public:
|
|||
}
|
||||
|
||||
// Updates the area that is visible inside the scroll container.
|
||||
virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||
auto max = height();
|
||||
visibleTopBottomUpdated(
|
||||
snap(visibleTop, 0, max),
|
||||
snap(visibleBottom, 0, max));
|
||||
}
|
||||
|
||||
signals:
|
||||
|
@ -418,11 +410,28 @@ signals:
|
|||
void heightUpdated();
|
||||
|
||||
protected:
|
||||
void setChildVisibleTopBottom(
|
||||
TWidget *child,
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
if (child) {
|
||||
auto top = child->y();
|
||||
child->setVisibleTopBottom(
|
||||
visibleTop - top,
|
||||
visibleBottom - top);
|
||||
}
|
||||
}
|
||||
|
||||
// Resizes content and counts natural widget height for the desired width.
|
||||
virtual int resizeGetHeight(int newWidth) {
|
||||
return height();
|
||||
}
|
||||
|
||||
virtual void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
|
|
|
@ -25,14 +25,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
|
||||
namespace Ui {
|
||||
|
||||
DiscreteSlider::DiscreteSlider(QWidget *parent) : TWidget(parent) {
|
||||
DiscreteSlider::DiscreteSlider(QWidget *parent) : RpWidget(parent) {
|
||||
setCursor(style::cur_pointer);
|
||||
}
|
||||
|
||||
void DiscreteSlider::setSectionActivatedCallback(SectionActivatedCallback &&callback) {
|
||||
_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void DiscreteSlider::setActiveSection(int index) {
|
||||
if (_activeIndex != index) {
|
||||
_activeIndex = index;
|
||||
|
@ -48,9 +44,7 @@ void DiscreteSlider::activateCallback() {
|
|||
}
|
||||
auto ms = getms();
|
||||
if (ms >= _callbackAfterMs) {
|
||||
if (_callback) {
|
||||
_callback();
|
||||
}
|
||||
_sectionActivated.fire_copy(_activeIndex);
|
||||
} else {
|
||||
_timerId = startTimer(_callbackAfterMs - ms, Qt::PreciseTimer);
|
||||
}
|
||||
|
@ -62,6 +56,10 @@ void DiscreteSlider::timerEvent(QTimerEvent *e) {
|
|||
|
||||
void DiscreteSlider::setActiveSectionFast(int index) {
|
||||
setActiveSection(index);
|
||||
finishAnimations();
|
||||
}
|
||||
|
||||
void DiscreteSlider::finishAnimations() {
|
||||
_a_left.finish();
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -20,13 +20,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "ui/rp_widget.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class RippleAnimation;
|
||||
|
||||
class DiscreteSlider : public TWidget {
|
||||
class DiscreteSlider : public RpWidget {
|
||||
public:
|
||||
DiscreteSlider(QWidget *parent);
|
||||
|
||||
|
@ -37,9 +39,11 @@ public:
|
|||
}
|
||||
void setActiveSection(int index);
|
||||
void setActiveSectionFast(int index);
|
||||
void finishAnimations();
|
||||
|
||||
using SectionActivatedCallback = base::lambda<void()>;
|
||||
void setSectionActivatedCallback(SectionActivatedCallback &&callback);
|
||||
rpl::producer<int> sectionActivated() const {
|
||||
return _sectionActivated.events();
|
||||
}
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
|
@ -88,7 +92,7 @@ private:
|
|||
int _activeIndex = 0;
|
||||
bool _selectOnPress = true;
|
||||
|
||||
SectionActivatedCallback _callback;
|
||||
rpl::event_stream<int> _sectionActivated;
|
||||
|
||||
int _pressed = -1;
|
||||
int _selected = 0;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue