From c1ae9e9680e05d5745be3da69f1d38e36759a082 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 11 Sep 2018 21:07:04 +0300 Subject: [PATCH] Implement intro wrap for new settings. --- .../SourceFiles/info/info_layer_widget.cpp | 1 - Telegram/SourceFiles/mainwindow.cpp | 5 +- Telegram/SourceFiles/settings/settings.style | 1 + .../SourceFiles/settings/settings_chat.cpp | 37 +- Telegram/SourceFiles/settings/settings_chat.h | 3 + .../SourceFiles/settings/settings_common.cpp | 2 +- .../SourceFiles/settings/settings_common.h | 2 +- .../SourceFiles/settings/settings_general.cpp | 50 +- .../SourceFiles/settings/settings_general.h | 7 + .../SourceFiles/settings/settings_intro.cpp | 526 ++++++++++++++++++ .../SourceFiles/settings/settings_intro.h | 51 ++ .../SourceFiles/settings/settings_main.cpp | 48 +- Telegram/SourceFiles/settings/settings_main.h | 8 + .../SourceFiles/window/window_controller.cpp | 18 +- Telegram/gyp/telegram_sources.txt | 2 + 15 files changed, 689 insertions(+), 72 deletions(-) create mode 100644 Telegram/SourceFiles/settings/settings_intro.cpp create mode 100644 Telegram/SourceFiles/settings/settings_intro.h diff --git a/Telegram/SourceFiles/info/info_layer_widget.cpp b/Telegram/SourceFiles/info/info_layer_widget.cpp index ed6239a29..f16c1627d 100644 --- a/Telegram/SourceFiles/info/info_layer_widget.cpp +++ b/Telegram/SourceFiles/info/info_layer_widget.cpp @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/info_layer_widget.h" -#include #include "info/info_content_widget.h" #include "info/info_top_bar.h" #include "info/info_memento.h" diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 7ad7ce1d3..d77c09cc3 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -33,7 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mediaview.h" #include "storage/localstorage.h" #include "apiwrap.h" -#include "old_settings/settings_widget.h" +#include "settings/settings_intro.h" #include "platform/platform_notifications_manager.h" #include "window/layer_widget.h" #include "window/notifications_manager.h" @@ -307,8 +307,7 @@ void MainWindow::showSettings() { if (const auto controller = this->controller()) { controller->showSettings(); } else { - // #TODO settings - showSpecialLayer(Box(), anim::type::normal); + showSpecialLayer(Box(), anim::type::normal); } } diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index e61fe672a..affab851d 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -30,6 +30,7 @@ settingsButtonRight: FlatLabel(defaultFlatLabel) { style: boxTextStyle; } settingsScalePadding: margins(79px, 10px, 28px, 8px); +settingsBigScalePadding: margins(24px, 10px, 24px, 8px); settingsSlider: SettingsSlider(defaultSettingsSlider) { barFg: windowBgOver; labelFg: windowSubTextFg; diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index 367ab9ea1..4a5e61fab 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -27,7 +27,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_settings.h" namespace Settings { -namespace { class BackgroundRow : public Ui::RpWidget { public: @@ -624,10 +623,7 @@ void SetupChatBackground(not_null container) { }, adaptive->lifetime()); } -void SetupThemeOptions(not_null container) { - AddDivider(container); - AddSkip(container); - +void SetupNightMode(not_null container) { const auto calling = Ui::AttachAsChild(container, 0); AddButton( container, @@ -648,16 +644,9 @@ void SetupThemeOptions(not_null container) { container, change); }, container->lifetime()); +} - AddButton( - container, - lng_settings_bg_edit_theme, - st::settingsButton - )->addClickHandler(App::LambdaDelayed( - st::settingsButton.ripple.hideDuration, - container, - [] { Window::Theme::Editor::Start(); })); - +void SetupUseDefaultTheme(not_null container) { using Update = const Window::Theme::BackgroundUpdate; container->add( object_ptr>( @@ -678,12 +667,28 @@ void SetupThemeOptions(not_null container) { })))->entity()->addClickHandler([] { Window::Theme::ApplyDefault(); }); +} + +void SetupThemeOptions(not_null container) { + AddDivider(container); + AddSkip(container); + + SetupNightMode(container); + + AddButton( + container, + lng_settings_bg_edit_theme, + st::settingsButton + )->addClickHandler(App::LambdaDelayed( + st::settingsButton.ripple.hideDuration, + container, + [] { Window::Theme::Editor::Start(); })); + + SetupUseDefaultTheme(container); AddSkip(container); } -} // namespace - Chat::Chat(QWidget *parent, not_null self) : Section(parent) , _self(self) { diff --git a/Telegram/SourceFiles/settings/settings_chat.h b/Telegram/SourceFiles/settings/settings_chat.h index ec1f577f3..41c91f516 100644 --- a/Telegram/SourceFiles/settings/settings_chat.h +++ b/Telegram/SourceFiles/settings/settings_chat.h @@ -11,6 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Settings { +void SetupNightMode(not_null container); +void SetupUseDefaultTheme(not_null container); + class Chat : public Section { public: Chat(QWidget *parent, not_null self); diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp index c2957c4af..9ca8056e6 100644 --- a/Telegram/SourceFiles/settings/settings_common.cpp +++ b/Telegram/SourceFiles/settings/settings_common.cpp @@ -28,7 +28,7 @@ namespace Settings { object_ptr
CreateSection( Type type, not_null parent, - not_null controller, + Window::Controller *controller, UserData *self) { switch (type) { case Type::Main: diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h index 43fa63fe2..8fe72174e 100644 --- a/Telegram/SourceFiles/settings/settings_common.h +++ b/Telegram/SourceFiles/settings/settings_common.h @@ -61,7 +61,7 @@ public: object_ptr
CreateSection( Type type, not_null parent, - not_null controller, + Window::Controller *controller = nullptr, UserData *self = nullptr); void AddSkip(not_null container); diff --git a/Telegram/SourceFiles/settings/settings_general.cpp b/Telegram/SourceFiles/settings/settings_general.cpp index 5f8a15122..307d35621 100644 --- a/Telegram/SourceFiles/settings/settings_general.cpp +++ b/Telegram/SourceFiles/settings/settings_general.cpp @@ -27,9 +27,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_settings.h" namespace Settings { -namespace { + +bool HasConnectionType() { +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY + return true; +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + return false; +} void SetupConnectionType(not_null container) { + if (!HasConnectionType()) { + return; + } #ifndef TDESKTOP_DISABLE_NETWORK_PROXY const auto connectionType = [] { const auto transport = MTP::dctransport(); @@ -74,14 +83,15 @@ void SetupStorageAndConnection(not_null container) { AddSkip(container); } +bool HasUpdate() { + return !Core::UpdaterDisabled(); +} + void SetupUpdate(not_null container) { - if (Core::UpdaterDisabled()) { + if (!HasUpdate()) { return; } - AddDivider(container); - AddSkip(container); - const auto texts = Ui::AttachAsChild( container, rpl::event_stream()); @@ -116,8 +126,6 @@ void SetupUpdate(not_null container) { update->moveToLeft(0, 0); }, update->lifetime()); - AddSkip(container); - rpl::combine( toggle->widthValue(), label->widthValue() @@ -218,14 +226,15 @@ void SetupUpdate(not_null container) { }); } +bool HasTray() { + return cSupportTray() || (cPlatform() == dbipWindows); +} + void SetupTray(not_null container) { - if (!cSupportTray() && cPlatform() != dbipWindows) { + if (!HasTray()) { return; } - AddDivider(container); - AddSkip(container); - const auto trayEnabler = Ui::AttachAsChild( container, rpl::event_stream()); @@ -369,12 +378,8 @@ void SetupTray(not_null container) { }, sendto->lifetime()); } #endif // OS_WIN_STORE - - AddSkip(container); } -} // namespace - General::General(QWidget *parent, UserData *self) : Section(parent) , _self(self) { @@ -385,8 +390,19 @@ void General::setupContent() { const auto content = Ui::CreateChild(this); AddSkip(content, st::settingsFirstDividerSkip); - SetupUpdate(content); - SetupTray(content); + + if (!Core::UpdaterDisabled()) { + AddDivider(content); + AddSkip(content); + SetupUpdate(content); + AddSkip(content); + } + if (HasTray()) { + AddDivider(content); + AddSkip(content); + SetupTray(content); + AddSkip(content); + } SetupStorageAndConnection(content); Ui::ResizeFitChild(this, content); diff --git a/Telegram/SourceFiles/settings/settings_general.h b/Telegram/SourceFiles/settings/settings_general.h index 3eacd95d2..2ef8c1a29 100644 --- a/Telegram/SourceFiles/settings/settings_general.h +++ b/Telegram/SourceFiles/settings/settings_general.h @@ -11,6 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Settings { +bool HasConnectionType(); +void SetupConnectionType(not_null container); +bool HasUpdate(); +void SetupUpdate(not_null container); +bool HasTray(); +void SetupTray(not_null container); + class General : public Section { public: explicit General(QWidget *parent, UserData *self = nullptr); diff --git a/Telegram/SourceFiles/settings/settings_intro.cpp b/Telegram/SourceFiles/settings/settings_intro.cpp new file mode 100644 index 000000000..dd8c3a0b6 --- /dev/null +++ b/Telegram/SourceFiles/settings/settings_intro.cpp @@ -0,0 +1,526 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "settings/settings_intro.h" + +#include "settings/settings_common.h" +#include "settings/settings_general.h" +#include "settings/settings_main.h" +#include "settings/settings_chat.h" +#include "settings/settings_codes.h" +#include "ui/wrap/fade_wrap.h" +#include "ui/wrap/vertical_layout.h" +#include "ui/widgets/shadow.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/scroll_area.h" +#include "lang/lang_keys.h" +#include "styles/style_settings.h" +#include "styles/style_boxes.h" +#include "styles/style_info.h" + +namespace Settings { +namespace { + +class TopBar : public Ui::RpWidget { +public: + TopBar(QWidget *parent, const style::InfoTopBar &st); + + void setTitle(rpl::producer &&title); + + template + ButtonWidget *addButton(base::unique_qptr button) { + auto result = button.get(); + pushButton(std::move(button)); + return result; + } + +protected: + int resizeGetHeight(int newWidth) override; + void paintEvent(QPaintEvent *e) override; + +private: + void updateControlsGeometry(int newWidth); + Ui::RpWidget *pushButton(base::unique_qptr button); + void removeButton(not_null button); + + const style::InfoTopBar &_st; + std::vector> _buttons; + QPointer _title; + +}; + +object_ptr CreateIntroSettings(QWidget *parent) { + auto result = object_ptr(parent); + + if (HasConnectionType()) { + AddDivider(result); + AddSkip(result); + SetupConnectionType(result); + AddSkip(result); + } + if (HasUpdate()) { + AddDivider(result); + AddSkip(result); + SetupUpdate(result); + AddSkip(result); + } + if (HasTray()) { + AddDivider(result); + AddSkip(result); + SetupTray(result); + AddSkip(result); + } + AddDivider(result); + AddSkip(result); + SetupInterfaceScale(result, false); + SetupNightMode(result); + SetupUseDefaultTheme(result); + AddSkip(result); + + AddDivider(result); + AddSkip(result); + SetupFaq(result, false); + AddSkip(result); + + return result; +} + +TopBar::TopBar(QWidget *parent, const style::InfoTopBar &st) +: RpWidget(parent) +, _st(st) { + setAttribute(Qt::WA_OpaquePaintEvent); +} + +void TopBar::setTitle(rpl::producer &&title) { + if (_title) { + delete _title; + } + _title = Ui::CreateChild( + this, + std::move(title), + _st.title); + updateControlsGeometry(width()); +} + +Ui::RpWidget *TopBar::pushButton(base::unique_qptr button) { + auto wrapped = std::move(button); + auto weak = wrapped.get(); + _buttons.push_back(std::move(wrapped)); + weak->widthValue( + ) | rpl::start_with_next([this] { + updateControlsGeometry(width()); + }, lifetime()); + return weak; +} + +void TopBar::removeButton(not_null button) { + _buttons.erase( + std::remove(_buttons.begin(), _buttons.end(), button), + _buttons.end()); +} + +int TopBar::resizeGetHeight(int newWidth) { + updateControlsGeometry(newWidth); + return _st.height; +} + +void TopBar::updateControlsGeometry(int newWidth) { + auto right = 0; + for (auto &button : _buttons) { + if (!button) continue; + button->moveToRight(right, 0, newWidth); + right += button->width(); + } + if (_title) { + _title->moveToLeft( + _st.titlePosition.x(), + _st.titlePosition.y(), + newWidth); + } +} + +void TopBar::paintEvent(QPaintEvent *e) { + Painter p(this); + p.fillRect(e->rect(), _st.bg); +} + +} // namespace + +class IntroWidget : public Ui::RpWidget { +public: + IntroWidget(QWidget *parent); + + void forceContentRepaint(); + + rpl::producer desiredHeightValue() const override; + + void updateGeometry(QRect newGeometry, int additionalScroll); + int scrollTillBottom(int forHeight) const; + rpl::producer scrollTillBottomChanges() const; + + void setInnerFocus(); + + ~IntroWidget(); + +protected: + void resizeEvent(QResizeEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + +private: + void updateControlsGeometry(); + QRect contentGeometry() const; + void setInnerWidget(object_ptr content); + void showContent(); + rpl::producer topShadowToggledValue() const; + void createTopBar(); + void applyAdditionalScroll(int additionalScroll); + + rpl::variable _scrollTopSkip = -1; + rpl::event_stream _scrollTillBottomChanges; + object_ptr _wrap; + not_null _scroll; + Ui::PaddingWrap *_innerWrap = nullptr; + int _innerDesiredHeight = 0; + + int _additionalScroll = 0; + object_ptr _topBar = { nullptr }; + + object_ptr _topShadow; + +}; + +IntroWidget::IntroWidget(QWidget *parent) +: RpWidget(parent) +, _topShadow(this) +, _wrap(this) +, _scroll(Ui::CreateChild(_wrap.data(), st::infoScroll)) { + _wrap->setAttribute(Qt::WA_OpaquePaintEvent); + _wrap->paintRequest( + ) | rpl::start_with_next([=](QRect clip) { + Painter p(_wrap.data()); + p.fillRect(clip, st::boxBg); + }, _wrap->lifetime()); + + _scrollTopSkip.changes( + ) | rpl::start_with_next([this] { + updateControlsGeometry(); + }, lifetime()); + + createTopBar(); + showContent(); + _topShadow->toggleOn( + topShadowToggledValue( + ) | rpl::filter([](bool shown) { + return true; + })); +} + +void IntroWidget::updateControlsGeometry() { + if (!_innerWrap) { + return; + } + + _topBar->resizeToWidth(width()); + _topShadow->resizeToWidth(width()); + _topShadow->moveToLeft(0, _topBar->height()); + _wrap->setGeometry(contentGeometry()); + + auto newScrollTop = _scroll->scrollTop(); + auto scrollGeometry = _wrap->rect().marginsRemoved( + QMargins(0, _scrollTopSkip.current(), 0, 0)); + if (_scroll->geometry() != scrollGeometry) { + _scroll->setGeometry(scrollGeometry); + _innerWrap->resizeToWidth(_scroll->width()); + } + + if (!_scroll->isHidden()) { + auto scrollTop = _scroll->scrollTop(); + _innerWrap->setVisibleTopBottom( + scrollTop, + scrollTop + _scroll->height()); + } +} + +void IntroWidget::forceContentRepaint() { + // WA_OpaquePaintEvent on TopBar creates render glitches when + // animating the LayerWidget's height :( Fixing by repainting. + + if (_topBar) { + _topBar->update(); + } + _scroll->update(); + if (_innerWrap) { + _innerWrap->update(); + } +} + +void IntroWidget::createTopBar() { + _topBar.create(this, st::infoLayerTopBar); + _topBar->setTitle(Lang::Viewer(lng_menu_settings)); + auto close = _topBar->addButton( + base::make_unique_q( + _topBar, + st::infoLayerTopBarClose)); + close->addClickHandler([] { + Ui::hideSettingsAndLayer(); + }); + + _topBar->lower(); + _topBar->resizeToWidth(width()); + _topBar->show(); +} + +void IntroWidget::setInnerWidget(object_ptr content) { + _innerWrap = _scroll->setOwnedWidget( + object_ptr>( + this, + std::move(content), + _innerWrap ? _innerWrap->padding() : style::margins())); + _innerWrap->move(0, 0); + + // MSVC BUG + REGRESSION rpl::mappers::tuple :( + rpl::combine( + _scroll->scrollTopValue(), + _scroll->heightValue(), + _innerWrap->entity()->desiredHeightValue() + ) | rpl::start_with_next([this]( + int top, + int height, + int desired) { + const auto bottom = top + height; + _innerDesiredHeight = desired; + _innerWrap->setVisibleTopBottom(top, bottom); + _scrollTillBottomChanges.fire_copy(std::max(desired - bottom, 0)); + }, _innerWrap->lifetime()); +} + +rpl::producer IntroWidget::topShadowToggledValue() const { + using namespace rpl::mappers; + return rpl::combine( + _scroll->scrollTopValue(), + _scrollTopSkip.value() + ) | rpl::map((_1 > 0) || (_2 > 0)); +} + +void IntroWidget::showContent() { + setInnerWidget(CreateIntroSettings(_scroll)); + + _additionalScroll = 0; + updateControlsGeometry(); + _topShadow->raise(); + _topShadow->finishAnimating(); +} + +void IntroWidget::setInnerFocus() { + setFocus(); +} + +rpl::producer IntroWidget::desiredHeightValue() const { + using namespace rpl::mappers; + return rpl::combine( + _topBar->heightValue(), + _innerWrap->entity()->desiredHeightValue(), + _scrollTopSkip.value() + ) | rpl::map(_1 + _2 + _3); +} + +QRect IntroWidget::contentGeometry() const { + return rect().marginsRemoved({ 0, _topBar->height(), 0, 0 }); +} + +void IntroWidget::resizeEvent(QResizeEvent *e) { + updateControlsGeometry(); +} + +void IntroWidget::keyPressEvent(QKeyEvent *e) { + CodesFeedString(e->text()); + return RpWidget::keyPressEvent(e); +} + +void IntroWidget::applyAdditionalScroll(int additionalScroll) { + if (_innerWrap) { + _innerWrap->setPadding({ 0, 0, 0, additionalScroll }); + } +} + +void IntroWidget::updateGeometry(QRect newGeometry, int additionalScroll) { + auto scrollChanged = (_additionalScroll != additionalScroll); + auto geometryChanged = (geometry() != newGeometry); + auto shrinkingContent = (additionalScroll < _additionalScroll); + _additionalScroll = additionalScroll; + + if (geometryChanged) { + if (shrinkingContent) { + setGeometry(newGeometry); + } + if (scrollChanged) { + applyAdditionalScroll(additionalScroll); + } + if (!shrinkingContent) { + setGeometry(newGeometry); + } + } else if (scrollChanged) { + applyAdditionalScroll(additionalScroll); + } +} + +int IntroWidget::scrollTillBottom(int forHeight) const { + auto scrollHeight = forHeight + - _scrollTopSkip.current() + - _topBar->height(); + auto scrollBottom = _scroll->scrollTop() + scrollHeight; + auto desired = _innerDesiredHeight; + return std::max(desired - scrollBottom, 0); +} + +rpl::producer IntroWidget::scrollTillBottomChanges() const { + return _scrollTillBottomChanges.events(); +} + +IntroWidget::~IntroWidget() = default; + +LayerWidget::LayerWidget(QWidget*) +: _content(this) { + setupHeightConsumers(); +} + +void LayerWidget::setupHeightConsumers() { + _content->scrollTillBottomChanges( + ) | rpl::filter([this] { + return !_inResize; + }) | rpl::start_with_next([this] { + resizeToWidth(width()); + }, lifetime()); + _content->desiredHeightValue( + ) | rpl::start_with_next([this](int height) { + accumulate_max(_desiredHeight, height); + if (_content && !_inResize) { + resizeToWidth(width()); + } + }, lifetime()); +} + +void LayerWidget::showFinished() { +} + +void LayerWidget::parentResized() { + const auto parentSize = parentWidget()->size(); + const auto parentWidth = parentSize.width(); + const auto newWidth = (parentWidth < MinimalSupportedWidth()) + ? parentWidth + : qMin( + parentWidth - 2 * st::infoMinimalLayerMargin, + st::infoDesiredWidth); + resizeToWidth(newWidth); +} + +int LayerWidget::MinimalSupportedWidth() { + auto minimalMargins = 2 * st::infoMinimalLayerMargin; + return st::infoMinimalWidth + minimalMargins; +} + +int LayerWidget::resizeGetHeight(int newWidth) { + if (!parentWidget() || !_content) { + return 0; + } + _inResize = true; + auto guard = gsl::finally([&] { _inResize = false; }); + + auto parentSize = parentWidget()->size(); + auto windowWidth = parentSize.width(); + auto windowHeight = parentSize.height(); + auto newLeft = (windowWidth - newWidth) / 2; + if (!newLeft) { + _content->updateGeometry({ + 0, + st::boxRadius, + windowWidth, + windowHeight - st::boxRadius }, 0); + auto newGeometry = QRect(0, 0, windowWidth, windowHeight); + if (newGeometry != geometry()) { + _content->forceContentRepaint(); + } + if (newGeometry.topLeft() != geometry().topLeft()) { + move(newGeometry.topLeft()); + } + _tillTop = _tillBottom = true; + return windowHeight; + } + auto newTop = snap( + windowHeight / 24, + st::infoLayerTopMinimal, + st::infoLayerTopMaximal); + auto newBottom = newTop; + auto desiredHeight = st::boxRadius + _desiredHeight + st::boxRadius; + accumulate_min(desiredHeight, windowHeight - newTop - newBottom); + + // First resize content to new width and get the new desired height. + auto contentLeft = 0; + auto contentTop = st::boxRadius; + auto contentBottom = st::boxRadius; + auto contentWidth = newWidth; + auto contentHeight = desiredHeight - contentTop - contentBottom; + auto scrollTillBottom = _content->scrollTillBottom(contentHeight); + auto additionalScroll = std::min(scrollTillBottom, newBottom); + + desiredHeight += additionalScroll; + contentHeight += additionalScroll; + _tillTop = false; + _tillBottom = (newTop + desiredHeight >= windowHeight); + if (_tillBottom) { + contentHeight += contentBottom; + additionalScroll += contentBottom; + } + _content->updateGeometry({ + contentLeft, + contentTop, + contentWidth, + contentHeight }, additionalScroll); + + auto newGeometry = QRect(newLeft, newTop, newWidth, desiredHeight); + if (newGeometry != geometry()) { + _content->forceContentRepaint(); + } + if (newGeometry.topLeft() != geometry().topLeft()) { + move(newGeometry.topLeft()); + } + + return desiredHeight; +} + +void LayerWidget::doSetInnerFocus() { + _content->setInnerFocus(); +} + +void LayerWidget::paintEvent(QPaintEvent *e) { + Painter p(this); + + auto clip = e->rect(); + auto r = st::boxRadius; + auto parts = RectPart::None | 0; + if (!_tillTop && clip.intersects({ 0, 0, width(), r })) { + parts |= RectPart::FullTop; + } + if (!_tillBottom && clip.intersects({ 0, height() - r, width(), r })) { + parts |= RectPart::FullBottom; + } + if (parts) { + App::roundRect( + p, + rect(), + st::boxBg, + BoxCorners, + nullptr, + parts); + } + if (_tillTop) { + p.fillRect(0, 0, width(), r, st::boxBg); + } +} + +} // namespace Info diff --git a/Telegram/SourceFiles/settings/settings_intro.h b/Telegram/SourceFiles/settings/settings_intro.h new file mode 100644 index 000000000..7fccf37e2 --- /dev/null +++ b/Telegram/SourceFiles/settings/settings_intro.h @@ -0,0 +1,51 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "window/layer_widget.h" + +namespace Ui { +class VerticalLayout; +class FadeShadow; +class FlatLabel; +template +class FadeWrap; +} // namespace Ui + +namespace Settings { + +class IntroWidget; + +class LayerWidget : public Window::LayerWidget { +public: + LayerWidget(QWidget*); + + void showFinished() override; + void parentResized() override; + + static int MinimalSupportedWidth(); + +protected: + int resizeGetHeight(int newWidth) override; + void doSetInnerFocus() override; + + void paintEvent(QPaintEvent *e) override; + +private: + void setupHeightConsumers(); + + object_ptr _content; + + int _desiredHeight = 0; + bool _inResize = false; + bool _tillTop = false; + bool _tillBottom = false; + +}; + +} // namespace Info diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index 037505e88..4bd52d397 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -26,7 +26,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_settings.h" namespace Settings { -namespace { void SetupUploadPhotoButton( not_null container, @@ -136,12 +135,16 @@ void SetupSections( AddSkip(container); } -void SetupInterfaceScale(not_null container) { - if (cRetina()) { +bool HasInterfaceScale() { + return !cRetina(); +} + +void SetupInterfaceScale( + not_null container, + bool icon) { + if (!HasInterfaceScale()) { return; } - AddDivider(container); - AddSkip(container); const auto toggled = Ui::AttachAsChild( container, @@ -152,13 +155,13 @@ void SetupInterfaceScale(not_null container) { const auto button = AddButton( container, lng_settings_default_scale, - st::settingsSectionButton, - &st::settingsIconInterfaceScale + icon ? st::settingsSectionButton : st::settingsGeneralButton, + icon ? &st::settingsIconInterfaceScale : nullptr )->toggleOn(toggled->events_starting_with_copy(switched)); const auto slider = container->add( object_ptr(container, st::settingsSlider), - st::settingsScalePadding); + icon ? st::settingsScalePadding : st::settingsBigScalePadding); const auto inSetScale = Ui::AttachAsChild(container, false); const auto setScale = std::make_shared>(); @@ -245,22 +248,24 @@ void SetupInterfaceScale(not_null container) { ) | rpl::start_with_next([=](int section) { (*setScale)(scaleByIndex(section)); }, slider->lifetime()); +} - AddSkip(container); +void SetupFaq(not_null container, bool icon) { + AddButton( + container, + lng_settings_faq, + icon ? st::settingsSectionButton : st::settingsGeneralButton, + icon ? &st::settingsIconFaq : nullptr + )->addClickHandler([] { + QDesktopServices::openUrl(telegramFaqLink()); + }); } void SetupHelp(not_null container) { AddDivider(container); AddSkip(container); - AddButton( - container, - lng_settings_faq, - st::settingsSectionButton, - &st::settingsIconFaq - )->addClickHandler([] { - QDesktopServices::openUrl(telegramFaqLink()); - }); + SetupFaq(container); if (AuthSession::Exists()) { const auto button = AddButton( @@ -281,8 +286,6 @@ void SetupHelp(not_null container) { AddSkip(container); } -} // namespace - Main::Main( QWidget *parent, not_null controller, @@ -310,7 +313,12 @@ void Main::setupContent(not_null controller) { SetupSections(content, [=](Type type) { _showOther.fire_copy(type); }); - SetupInterfaceScale(content); + if (HasInterfaceScale()) { + AddDivider(content); + AddSkip(content); + SetupInterfaceScale(content); + AddSkip(content); + } SetupHelp(content); Ui::ResizeFitChild(this, content); diff --git a/Telegram/SourceFiles/settings/settings_main.h b/Telegram/SourceFiles/settings/settings_main.h index b98842661..c0b4e079e 100644 --- a/Telegram/SourceFiles/settings/settings_main.h +++ b/Telegram/SourceFiles/settings/settings_main.h @@ -19,6 +19,14 @@ class VerticalLayout; namespace Settings { +bool HasInterfaceScale(); +void SetupInterfaceScale( + not_null container, + bool icon = true); +void SetupFaq( + not_null container, + bool icon = true); + class Main : public Section { public: Main( diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index f2c9217cd..5fc85d296 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "window/main_window.h" -#include "old_settings/settings_widget.h" #include "info/info_memento.h" #include "info/info_controller.h" #include "history/history.h" @@ -478,18 +477,11 @@ void Navigation::showPeerInfo( void Navigation::showSettings( Settings::Type type, const SectionShow ¶ms) { - if (AuthSession::Exists()) { - showSection( - Info::Memento( - Info::Settings::Tag{ Auth().user() }, - Info::Section(type)), - params); - } else { - // #TODO settings - App::wnd()->showSpecialLayer( - Box(), - params.animated); - } + showSection( + Info::Memento( + Info::Settings::Tag{ Auth().user() }, + Info::Section(type)), + params); } void Navigation::showSettings(const SectionShow ¶ms) { diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index ec8ba4245..5847e1a3e 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -574,6 +574,8 @@ <(src_loc)/settings/settings_general.h <(src_loc)/settings/settings_information.cpp <(src_loc)/settings/settings_information.h +<(src_loc)/settings/settings_intro.cpp +<(src_loc)/settings/settings_intro.h <(src_loc)/settings/settings_main.cpp <(src_loc)/settings/settings_main.h <(src_loc)/settings/settings_notifications.cpp