From 993b91ac1567d36219353f73244beef2a6516df9 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 22 Aug 2016 19:16:21 +0200 Subject: [PATCH] Most of the new Settings sections filled with widgets. Some animations added: new scale slider, widget_slide_wrap. Any TWidget now can resizeToWidth() with overriden resizeGetHeight(). --- Telegram/Resources/langs/lang.strings | 5 +- Telegram/Resources/winrc/Telegram.rc | 8 +- Telegram/Resources/winrc/Updater.rc | 8 +- Telegram/SourceFiles/core/version.h | 4 +- Telegram/SourceFiles/historywidget.cpp | 9 +- Telegram/SourceFiles/historywidget.h | 9 +- Telegram/SourceFiles/layerwidget.cpp | 6 +- Telegram/SourceFiles/layerwidget.h | 1 + .../SourceFiles/profile/profile_cover.cpp | 13 +- Telegram/SourceFiles/profile/profile_cover.h | 7 +- .../SourceFiles/profile/profile_fixed_bar.cpp | 11 +- .../SourceFiles/profile/profile_fixed_bar.h | 3 +- .../profile/profile_inner_widget.cpp | 11 +- .../profile/profile_inner_widget.h | 13 +- Telegram/SourceFiles/settings/settings.style | 24 +- .../settings/settings_advanced_widget.cpp | 69 ++++- .../settings/settings_advanced_widget.h | 30 ++- .../settings/settings_block_widget.cpp | 45 ++++ .../settings/settings_block_widget.h | 63 ++++- .../settings_chat_settings_widget.cpp | 113 ++++++++- .../settings/settings_chat_settings_widget.h | 48 +++- .../settings/settings_fixed_bar.cpp | 4 +- .../SourceFiles/settings/settings_fixed_bar.h | 4 +- .../settings/settings_general_widget.cpp | 171 ++++++++++++- .../settings/settings_general_widget.h | 45 +++- .../settings/settings_info_widget.cpp | 169 ++++++++++++- .../settings/settings_info_widget.h | 49 ++-- .../settings/settings_inner_widget.cpp | 37 ++- .../settings/settings_inner_widget.h | 20 +- .../settings_notifications_widget.cpp | 96 ++++++- .../settings/settings_notifications_widget.h | 23 +- .../settings/settings_privacy_widget.cpp | 20 +- .../settings/settings_privacy_widget.h | 13 +- .../settings/settings_scale_widget.cpp | 235 +++++++++++++++++- .../settings/settings_scale_widget.h | 64 ++++- Telegram/SourceFiles/settingswidget.cpp | 4 +- .../ui/buttons/left_outline_button.cpp | 4 +- .../ui/buttons/left_outline_button.h | 3 +- Telegram/SourceFiles/ui/flatbutton.cpp | 4 + Telegram/SourceFiles/ui/flatbutton.h | 9 +- Telegram/SourceFiles/ui/flatcheckbox.cpp | 4 + Telegram/SourceFiles/ui/flatcheckbox.h | 5 +- Telegram/SourceFiles/ui/flatlabel.cpp | 8 +- Telegram/SourceFiles/ui/flatlabel.h | 5 +- Telegram/SourceFiles/ui/scrollarea.h | 11 - Telegram/SourceFiles/ui/twidget.h | 19 +- .../ui/widgets/widget_slide_wrap.h | 164 ++++++++++++ Telegram/SourceFiles/ui/widgets/widgets.style | 2 + Telegram/build/version | 4 +- Telegram/gyp/Telegram.gyp | 1 + 50 files changed, 1516 insertions(+), 181 deletions(-) create mode 100644 Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index a10cd9242..4e93f0dcb 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -253,7 +253,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_change_lang" = "Change language"; "lng_languages" = "Languages"; "lng_sure_save_language" = "Telegram will restart in order to change language"; -"lng_settings_auto_update" = "Update automatically"; +"lng_settings_update_automatically" = "Update automatically (ver. {version})"; "lng_settings_current_version" = "Version {version}"; "lng_settings_check_now" = "Check for updates"; "lng_settings_update_checking" = "Checking for updates..."; @@ -314,7 +314,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_local_storage_cleared" = "Cleared!"; "lng_local_storage_clear_failed" = "Clear failed :("; -"lng_settings_section_advanced" = "Advanced"; +"lng_settings_section_advanced_settings" = "Advanced Settings"; "lng_passcode_remove_button" = "Remove"; @@ -388,6 +388,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_reset_one_sure" = "Do you want to terminate this session?"; "lng_settings_reset_button" = "Terminate"; "lng_settings_reset_done" = "Other sessions terminated"; +"lng_settings_manage_local_storage" = "Manage local storage"; "lng_settings_ask_question" = "Ask a Question"; "lng_settings_ask_sure" = "Please note that Telegram Support is done by volunteers. We try to respond as quickly as possible, but it may take a while.\n\nPlease take a look at the Telegram FAQ: it has important troubleshooting tips and answers to most questions."; "lng_settings_faq_button" = "Go to FAQ"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index b0e73a599..8b635743b 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,2,0 - PRODUCTVERSION 0,10,2,0 + FILEVERSION 0,10,2,1 + PRODUCTVERSION 0,10,2,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.2.0" + VALUE "FileVersion", "0.10.2.1" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.2.0" + VALUE "ProductVersion", "0.10.2.1" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 4c73c83cc..afb6ca25f 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,2,0 - PRODUCTVERSION 0,10,2,0 + FILEVERSION 0,10,2,1 + PRODUCTVERSION 0,10,2,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.10.2.0" + VALUE "FileVersion", "0.10.2.1" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.2.0" + VALUE "ProductVersion", "0.10.2.1" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index a64039b9b..8ff546895 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,9 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/basic_types.h" -#define BETA_VERSION_MACRO (0ULL) +#define BETA_VERSION_MACRO (10002001ULL) constexpr int AppVersion = 10002; constexpr str_const AppVersionStr = "0.10.2"; -constexpr bool AppAlphaVersion = true; +constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 2d838b467..3e56f14a6 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2557,9 +2557,7 @@ bool BotKeyboard::forceReply() const { return _forceReply; } -void BotKeyboard::resizeToWidth(int newWidth, int maxOuterHeight) { - _maxOuterHeight = maxOuterHeight; - +int BotKeyboard::resizeGetHeight(int newWidth) { updateStyle(newWidth); _height = st::botKbScroll.deltat + st::botKbScroll.deltab + (_impl ? _impl->naturalHeight() : 0); if (_maximizeSize) { @@ -2570,10 +2568,7 @@ void BotKeyboard::resizeToWidth(int newWidth, int maxOuterHeight) { int implHeight = _height - (st::botKbScroll.deltat + st::botKbScroll.deltab); _impl->resize(implWidth, implHeight); } - QSize newSize(newWidth, _height); - if (newSize != size()) { - resize(newSize); - } + return _height; } bool BotKeyboard::maximizeSize() const { diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 3bf3e59a7..8c08638a4 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -354,7 +354,6 @@ class BotKeyboard : public TWidget, public AbstractTooltipShower, public ClickHa Q_OBJECT public: - BotKeyboard(); void paintEvent(QPaintEvent *e) override; @@ -373,7 +372,10 @@ public: bool forceReply() const; void step_selected(uint64 ms, bool timer); - void resizeToWidth(int newWidth, int maxOuterHeight); + void resizeToWidth(int newWidth, int maxOuterHeight) { + _maxOuterHeight = maxOuterHeight; + return TWidget::resizeToWidth(newWidth); + } bool maximizeSize() const; bool singleUse() const; @@ -390,6 +392,9 @@ public: void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; +protected: + int resizeGetHeight(int newWidth) override; + private: void updateSelected(); diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index e312b8189..0244ffa0e 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -107,11 +107,15 @@ void LayerStackWidget::paintEvent(QPaintEvent *e) { void LayerStackWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { - onClose(); + onCloseCurrent(); } } void LayerStackWidget::mousePressEvent(QMouseEvent *e) { + onCloseCurrent(); +} + +void LayerStackWidget::onCloseCurrent() { if (layer()) { onCloseLayers(); } else { diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index 825829e76..32c642092 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -73,6 +73,7 @@ public: bool contentOverlapped(const QRect &globalRect); + void onCloseCurrent(); void onCloseLayers(); void onClose(); diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index b3504b829..056b2f07c 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -111,7 +111,7 @@ int CoverWidget::countPhotoLeft(int newWidth) const { return qMin(result, st::profilePhotoLeftMax); } -void CoverWidget::resizeToWidth(int newWidth) { +int CoverWidget::resizeGetHeight(int newWidth) { int newHeight = 0; newHeight += st::profileMarginTop; @@ -137,9 +137,8 @@ void CoverWidget::resizeToWidth(int newWidth) { newHeight += st::profileBlocksTop; - resizeDropArea(); - resize(newWidth, newHeight); - update(); + resizeDropArea(newWidth); + return newHeight; } void CoverWidget::refreshNameGeometry(int newWidth) { @@ -210,9 +209,9 @@ void CoverWidget::paintEvent(QPaintEvent *e) { paintDivider(p); } -void CoverWidget::resizeDropArea() { +void CoverWidget::resizeDropArea(int newWidth) { if (_dropArea) { - _dropArea->setGeometry(0, 0, width(), _dividerTop); + _dropArea->setGeometry(0, 0, newWidth, _dividerTop); } } @@ -277,7 +276,7 @@ void CoverWidget::dragEnterEvent(QDragEnterEvent *e) { subtitle = lang(lng_profile_drop_area_subtitle_channel); } _dropArea = new CoverDropArea(this, title, subtitle); - resizeDropArea(); + resizeDropArea(width()); } _dropArea->showAnimated(); e->setDropAction(Qt::CopyAction); diff --git a/Telegram/SourceFiles/profile/profile_cover.h b/Telegram/SourceFiles/profile/profile_cover.h index d7034ef93..5b3c8023b 100644 --- a/Telegram/SourceFiles/profile/profile_cover.h +++ b/Telegram/SourceFiles/profile/profile_cover.h @@ -46,9 +46,6 @@ class CoverWidget final : public TWidget, public Notify::Observer { public: CoverWidget(QWidget *parent, PeerData *peer); - // Count new height for width=newWidth and resize to it. - void resizeToWidth(int newWidth); - void showFinished(); // Profile fixed top bar should use this flag to decide @@ -78,6 +75,8 @@ protected: void dragLeaveEvent(QDragLeaveEvent *e) override; void dropEvent(QDropEvent *e) override; + int resizeGetHeight(int newWidth) override; + private: // Observed notifications. void notifyPeerUpdated(const Notify::PeerUpdate &update); @@ -105,7 +104,7 @@ private: bool canEditPhoto() const; void showSetPhotoBox(const QImage &img); - void resizeDropArea(); + void resizeDropArea(int newWidth); void dropAreaHidden(CoverDropArea *dropArea); bool mimeDataHasImage(const QMimeData *mimeData) const; diff --git a/Telegram/SourceFiles/profile/profile_fixed_bar.cpp b/Telegram/SourceFiles/profile/profile_fixed_bar.cpp index f7b9d9a7d..8d2cde28b 100644 --- a/Telegram/SourceFiles/profile/profile_fixed_bar.cpp +++ b/Telegram/SourceFiles/profile/profile_fixed_bar.cpp @@ -37,11 +37,10 @@ public: setCursor(style::cur_pointer); } - void resizeToWidth(int newWidth) { - resize(newWidth, st::profileTopBarHeight); - } - protected: + int resizeGetHeight(int newWidth) override { + return st::profileTopBarHeight; + } void paintEvent(QPaintEvent *e) override { Painter p(this); @@ -224,7 +223,7 @@ void FixedBar::onLeaveGroupSure() { App::main()->deleteAndExit(_peerChat); } -void FixedBar::resizeToWidth(int newWidth) { +int FixedBar::resizeGetHeight(int newWidth) { int newHeight = 0; int buttonLeft = newWidth; @@ -238,7 +237,7 @@ void FixedBar::resizeToWidth(int newWidth) { _backButton->moveToLeft(0, 0); newHeight += _backButton->height(); - resize(newWidth, newHeight); + return newHeight; } void FixedBar::setAnimatingMode(bool enabled) { diff --git a/Telegram/SourceFiles/profile/profile_fixed_bar.h b/Telegram/SourceFiles/profile/profile_fixed_bar.h index de03c7e0d..3030eef49 100644 --- a/Telegram/SourceFiles/profile/profile_fixed_bar.h +++ b/Telegram/SourceFiles/profile/profile_fixed_bar.h @@ -40,8 +40,6 @@ class FixedBar final : public TWidget, public Notify::Observer { public: FixedBar(QWidget *parent, PeerData *peer); - void resizeToWidth(int newWidth); - // When animating mode is enabled the content is hidden and the // whole fixed bar acts like a back button. void setAnimatingMode(bool enabled); @@ -51,6 +49,7 @@ public: protected: void mousePressEvent(QMouseEvent *e) override; + int resizeGetHeight(int newWidth) override; public slots: void onBack(); diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.cpp b/Telegram/SourceFiles/profile/profile_inner_widget.cpp index 480bda60e..de59ee911 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_inner_widget.cpp @@ -69,12 +69,6 @@ void InnerWidget::createBlocks() { } } -void InnerWidget::resizeToWidth(int newWidth, int minHeight) { - int naturalHeight = resizeGetHeight(newWidth); - _addedHeight = qMax(minHeight - naturalHeight, 0); - resize(newWidth, naturalHeight + _addedHeight); -} - void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) { _visibleTop = visibleTop; _visibleBottom = visibleBottom; @@ -225,7 +219,10 @@ int InnerWidget::resizeGetHeight(int newWidth) { refreshBlocksPositions(); update(); - return countHeight(); + auto naturalHeight = countHeight(); + + _addedHeight = qMax(_minHeight - naturalHeight, 0); + return naturalHeight + _addedHeight; } int InnerWidget::countHeight() const { diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.h b/Telegram/SourceFiles/profile/profile_inner_widget.h index 61467d55b..64cc9b4a7 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.h +++ b/Telegram/SourceFiles/profile/profile_inner_widget.h @@ -35,8 +35,10 @@ public: return _peer; } - // Count new height for width=newWidth and resize to it. - void resizeToWidth(int newWidth, int minHeight); + void resizeToWidth(int newWidth, int minHeight) { + _minHeight = minHeight; + return TWidget::resizeToWidth(newWidth); + } // Updates the area that is visible inside the scroll container. void setVisibleTopBottom(int visibleTop, int visibleBottom); @@ -58,12 +60,12 @@ protected: 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(); - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth); - // Counts the natural widget height after resizing of child widgets. int countHeight() const; @@ -92,6 +94,7 @@ private: // Height that we added to the natural height so that it is allowed // to scroll down to the desired position. int _addedHeight = 0; + int _minHeight = 0; int _visibleTop = 0; int _visibleBottom = 0; diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 16094e9cc..c1102e527 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -86,8 +86,9 @@ settingsSecondaryButton: RoundButton(settingsPrimaryButton) { settingsBlocksTop: 7px; settingsBlocksBottom: 20px; settingsBlockMarginTop: 14px; -settingsBlockMarginBottom: 7px; -settingsBlockTitleHeight: 24px; +settingsBlockMarginRight: 10px; +settingsBlockMarginBottom: 16px; +settingsBlockTitleHeight: 31px; settingsBlockTitleFont: font(14px semibold); settingsBlockTitleFg: #333333; settingsBlockTitleTop: 0px; @@ -99,5 +100,20 @@ settingsBlockOneLineTextPart: flatLabel(labelDefFlat) { margin: margins(5px, 5px, 5px, 5px); maxHeight: 20px; } -settingsBlockOneLineSkip: 9px; -settingsBlockOneLineWidthMax: 240px; +settingsSubSkip: 4px; +settingsSmallSkip: 10px; +settingsSkip: 15px; +settingsLargeSkip: 23px; + +settingsActionPadding: margins(0px, 4px, 0px, 5px); + +settingsSliderHeight: 39px; +settingsSliderTop: 5px; +settingsSliderSkip: 3px; +settingsSliderThickness: 3px; +settingsSliderActiveFg: #4bb5e7; +settingsSliderInactiveFg: #e1eaef; +settingsSliderLabelTop: 17px; +settingsSliderLabelFont: normalFont; +settingsSliderLabelFg: #1485c2; +settingsSliderDuration: 200; diff --git a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp index dab88d9e8..69f1c72b5 100644 --- a/Telegram/SourceFiles/settings/settings_advanced_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced_widget.cpp @@ -23,21 +23,76 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "boxes/connectionbox.h" +#include "boxes/confirmbox.h" +#include "boxes/aboutbox.h" +#include "mainwindow.h" namespace Settings { -AdvancedWidget::AdvancedWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_advanced)) { - refreshControls(); +AdvancedWidget::AdvancedWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_advanced_settings)) { + createControls(); } -void AdvancedWidget::refreshControls() { +void AdvancedWidget::createControls() { + style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); + style::margins marginLarge(0, 0, 0, st::settingsLargeSkip); + + if (self()) { + addChildRow(_manageLocalStorage, marginSmall, 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)); + connect(_connectionType->link(), SIGNAL(clicked()), this, SLOT(onConnectionType())); +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + if (self()) { + addChildRow(_askQuestion, marginSmall, lang(lng_settings_ask_question), SLOT(onAskQuestion())); + } + addChildRow(_telegramFAQ, marginLarge, lang(lng_settings_faq), SLOT(onTelegramFAQ())); + if (self()) { + addChildRow(_logOut, marginSmall, lang(lng_settings_logout), SLOT(onLogOut())); + } } -int AdvancedWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void AdvancedWidget::onManageLocalStorage() { - newHeight += st::settingsBlockMarginBottom; - return newHeight; } +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY +void AdvancedWidget::onConnectionType() { + Ui::showLayer(new ConnectionBox()); +} +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + +void AdvancedWidget::onAskQuestion() { + ConfirmBox *box = new ConfirmBox(lang(lng_settings_ask_sure), lang(lng_settings_ask_ok), st::defaultBoxButton, lang(lng_settings_faq_button)); + connect(box, SIGNAL(confirmed()), this, SLOT(onAskQuestionSure())); + connect(box, SIGNAL(cancelPressed()), this, SLOT(onTelegramFAQ())); + Ui::showLayer(box); +} + +void AdvancedWidget::onAskQuestionSure() { + if (_supportGetRequest) return; + _supportGetRequest = MTP::send(MTPhelp_GetSupport(), rpcDone(&AdvancedWidget::supportGot)); +} + +void AdvancedWidget::supportGot(const MTPhelp_Support &support) { + if (!App::main()) return; + + if (support.type() == mtpc_help_support) { + if (auto user = App::feedUsers(MTP_vector(1, support.c_help_support().vuser))) { + Ui::showPeerHistory(user, ShowAtUnreadMsgId); + } + } +} + +void AdvancedWidget::onTelegramFAQ() { + QDesktopServices::openUrl(telegramFaqLink()); +} + +void AdvancedWidget::onLogOut() { + App::wnd()->onLogout(); +} + + } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_advanced_widget.h b/Telegram/SourceFiles/settings/settings_advanced_widget.h index bc284ed91..001a2a124 100644 --- a/Telegram/SourceFiles/settings/settings_advanced_widget.h +++ b/Telegram/SourceFiles/settings/settings_advanced_widget.h @@ -21,19 +21,39 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "settings/settings_block_widget.h" +#include "settings/settings_chat_settings_widget.h" namespace Settings { -class AdvancedWidget : public BlockWidget { +class AdvancedWidget : public BlockWidget, public RPCSender { + Q_OBJECT + public: AdvancedWidget(QWidget *parent, UserData *self); -protected: - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override; +private slots: + void onManageLocalStorage(); +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY + void onConnectionType(); +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + void onAskQuestion(); + void onAskQuestionSure(); + void onTelegramFAQ(); + void onLogOut(); private: - void refreshControls(); + void createControls(); + void supportGot(const MTPhelp_Support &support); + + ChildWidget _manageLocalStorage = { nullptr }; +#ifndef TDESKTOP_DISABLE_NETWORK_PROXY + ChildWidget _connectionType = { nullptr }; +#endif // TDESKTOP_DISABLE_NETWORK_PROXY + ChildWidget _askQuestion = { nullptr }; + ChildWidget _telegramFAQ = { nullptr }; + ChildWidget _logOut = { nullptr }; + + mtpRequestId _supportGetRequest = 0; }; diff --git a/Telegram/SourceFiles/settings/settings_block_widget.cpp b/Telegram/SourceFiles/settings/settings_block_widget.cpp index fe7e0697d..4052ccc37 100644 --- a/Telegram/SourceFiles/settings/settings_block_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_block_widget.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "settings/settings_block_widget.h" #include "styles/style_settings.h" +#include "ui/flatcheckbox.h" namespace Settings { @@ -38,6 +39,23 @@ int BlockWidget::contentTop() const { return emptyTitle() ? 0 : (st::settingsBlockMarginTop + st::settingsBlockTitleHeight); } +int BlockWidget::resizeGetHeight(int newWidth) { + int x = contentLeft(), result = contentTop(); + int availw = newWidth - x; + for_const (auto &row, _rows) { + row.child->moveToLeft(x + row.margin.left(), result + row.margin.top()); + auto availRowWidth = availw - row.margin.left() - row.margin.right(); + auto natural = row.child->naturalWidth(); + auto rowWidth = (natural < 0) ? (availRowWidth - x) : qMin(natural, availRowWidth); + if (row.child->width() != rowWidth) { + row.child->resizeToWidth(rowWidth); + } + result += row.child->height() + row.margin.top() + row.margin.bottom(); + } + result += st::settingsBlockMarginBottom; + return result; +} + void BlockWidget::paintEvent(QPaintEvent *e) { Painter p(this); @@ -54,4 +72,31 @@ void BlockWidget::paintTitle(Painter &p) { p.drawTextLeft(contentLeft(), titleTop, width(), _title); } +void BlockWidget::addCreatedRow(TWidget *child, const style::margins &margin) { + _rows.push_back({ child, margin }); +} + +void BlockWidget::rowHeightUpdated() { + auto newHeight = resizeGetHeight(width()); + if (newHeight != height()) { + resize(width(), newHeight); + emit heightUpdated(); + } +} + +void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, bool checked) { + child = new Checkbox(this, text, checked); + connect(child, SIGNAL(changed()), this, slot); +} + +void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked) { + child = new Radiobutton(this, group, value, text, checked); + connect(child, SIGNAL(changed()), this, slot); +} + +void BlockWidget::createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot) { + child = new LinkButton(this, text); + connect(child, SIGNAL(changed()), this, slot); +} + } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_block_widget.h b/Telegram/SourceFiles/settings/settings_block_widget.h index 4df35cd90..9e3afb21a 100644 --- a/Telegram/SourceFiles/settings/settings_block_widget.h +++ b/Telegram/SourceFiles/settings/settings_block_widget.h @@ -22,6 +22,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/observer.h" +class Checkbox; +class Radiobutton; + +namespace Ui { +template +class WidgetSlideWrap; +} // namespace Ui + namespace Settings { class BlockWidget : public ScrolledWidget, public Notify::Observer, public base::Subscriber { @@ -44,7 +52,7 @@ protected: int contentTop() const; // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override = 0; + int resizeGetHeight(int newWidth) override; void contentSizeUpdated() { resizeToWidth(width()); @@ -59,9 +67,62 @@ protected: return _title.isEmpty(); } + template + Widget *addChildRow(ChildWidget &child, style::margins margin, Args&&... args) { + createChildRow(child, margin, std_::forward(args)...); + addCreatedRow(child, margin); + return child; + } + private: + template + void createChildRow(ChildWidget> &child, style::margins &margin, const style::margins &padding, Args&&... args) { + ChildWidget plainChild = { nullptr }; + createChildRow(plainChild, margin, std_::forward(args)...); + child = new Ui::WidgetSlideWrap(this, plainChild, padding, [this]() { + rowHeightUpdated(); + }); + 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(ChildWidget &child, style::margins &margin, const QString &text, const char *slot, bool checked); + void createChildRow(ChildWidget &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked); + void createChildRow(ChildWidget &child, style::margins &margin, const QString &text, const char *slot); + + void addCreatedRow(TWidget *child, const style::margins &margin); + void rowHeightUpdated(); + + template + struct IsWidgetSlideWrap { + static constexpr bool value = false; + }; + template + struct IsWidgetSlideWrap> { + static constexpr bool value = true; + }; + + template + using NotImplementedYet = std_::enable_if_t< + !IsWidgetSlideWrap::value && + !std_::is_same::value && + !std_::is_same::value && + !std_::is_same::value>; + + template > + void createChildRow(ChildWidget &child, style::margins &margin, Args&&... args) { + child = new Widget(this, std_::forward(args)...); + } + void paintTitle(Painter &p); + struct ChildRow { + TWidget *child; + style::margins margin; + }; + QVector _rows; + int _contentLeft = 0; UserData *_self; QString _title; diff --git a/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp b/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp index 405174c55..3d6e01fd1 100644 --- a/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_chat_settings_widget.cpp @@ -23,21 +23,122 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "ui/widgets/widget_slide_wrap.h" +#include "ui/flatlabel.h" +#include "localstorage.h" +#include "mainwidget.h" +#include "boxes/emojibox.h" +#include "boxes/stickersetbox.h" +#include "boxes/downloadpathbox.h" +#include "boxes/connectionbox.h" namespace Settings { ChatSettingsWidget::ChatSettingsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_chat_settings)) { - refreshControls(); + createControls(); } -void ChatSettingsWidget::refreshControls() { +void ChatSettingsWidget::createControls() { + style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); + style::margins marginSkip(0, 0, 0, st::settingsSkip); + style::margins marginSub(0, 0, 0, st::settingsSubSkip); + style::margins slidedPadding(0, marginSub.bottom() / 2, 0, marginSub.bottom() - (marginSub.bottom() / 2)); + + addChildRow(_replaceEmoji, marginSub, lang(lng_settings_replace_emojis), SLOT(onReplaceEmoji()), cReplaceEmojis()); + style::margins marginList(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + addChildRow(_viewList, marginList, slidedPadding, lang(lng_settings_view_emojis), SLOT(onViewList())); + + addChildRow(_dontAskDownloadPath, marginSub, lang(lng_download_path_dont_ask), SLOT(onDontAskDownloadPath()), !cAskDownloadPath()); + auto downloadPathText = []() -> QString { + if (cDownloadPath().isEmpty()) { + return lang(lng_download_path_default); + } else if (cDownloadPath() == qsl("tmp")) { + return lang(lng_download_path_temp); + } + return QDir::toNativeSeparators(cDownloadPath()); + }; + style::margins marginPath(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + addChildRow(_downloadPath, marginPath, slidedPadding, lang(lng_download_path_label), downloadPathText()); + connect(_downloadPath->entity()->link(), SIGNAL(clicked()), this, SLOT(onDownloadPath())); + + addChildRow(_sendByEnter, marginSmall, qsl("send_key"), 0, lang(lng_settings_send_enter), SLOT(onSendByEnter()), !cCtrlEnter()); + addChildRow(_sendByCtrlEnter, marginSkip, qsl("send_key"), 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), SLOT(onSendByCtrlEnter()), cCtrlEnter()); + addChildRow(_automaticMediaDownloadSettings, marginSmall, lang(lng_media_auto_settings), SLOT(onAutomaticMediaDownloadSettings())); + addChildRow(_manageStickerSets, marginSmall, lang(lng_stickers_you_have), SLOT(onManageStickerSets())); } -int ChatSettingsWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text) : TWidget(parent) +, _label(this, label, FlatLabel::InitType::Simple) +, _link(this, text) { +} - newHeight += st::settingsBlockMarginBottom; - return newHeight; +void LabeledLink::setLink(const QString &text) { + _link.destroy(); + _link = new LinkButton(this, text); +} + +int LabeledLink::naturalWidth() const { + return _label->naturalWidth() + st::normalFont->spacew + _link->naturalWidth(); +} + +int LabeledLink::resizeGetHeight(int newWidth) { + _label->moveToLeft(0, 0); + _link->resizeToWidth(newWidth - st::normalFont->spacew - _label->width()); + _link->moveToLeft(_label->width() + st::normalFont->spacew, 0); + return _label->height(); +} + +void ChatSettingsWidget::onReplaceEmoji() { + cSetReplaceEmojis(_replaceEmoji->checked()); + Local::writeUserSettings(); + + if (_replaceEmoji->checked()) { + _viewList->slideDown(); + } else { + _viewList->slideUp(); + } +} + +void ChatSettingsWidget::onViewList() { + Ui::showLayer(new EmojiBox()); +} + +void ChatSettingsWidget::onDontAskDownloadPath() { + cSetAskDownloadPath(!_dontAskDownloadPath->checked()); + Local::writeUserSettings(); + if (_dontAskDownloadPath->checked()) { + _downloadPath->slideDown(); + } else { + _downloadPath->slideUp(); + } +} + +void ChatSettingsWidget::onDownloadPath() { + Ui::showLayer(new DownloadPathBox()); +} + +void ChatSettingsWidget::onSendByEnter() { + if (_sendByEnter->checked()) { + cSetCtrlEnter(false); + if (App::main()) App::main()->ctrlEnterSubmitUpdated(); + Local::writeUserSettings(); + } +} + +void ChatSettingsWidget::onSendByCtrlEnter() { + if (_sendByCtrlEnter->checked()) { + cSetCtrlEnter(true); + if (App::main()) App::main()->ctrlEnterSubmitUpdated(); + Local::writeUserSettings(); + } +} + +void ChatSettingsWidget::onAutomaticMediaDownloadSettings() { + Ui::showLayer(new AutoDownloadBox()); +} + +void ChatSettingsWidget::onManageStickerSets() { + Ui::showLayer(new StickersBox()); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_chat_settings_widget.h b/Telegram/SourceFiles/settings/settings_chat_settings_widget.h index 726bf4cfe..208c6ea76 100644 --- a/Telegram/SourceFiles/settings/settings_chat_settings_widget.h +++ b/Telegram/SourceFiles/settings/settings_chat_settings_widget.h @@ -22,18 +22,58 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "settings/settings_block_widget.h" +class FlatLabel; + namespace Settings { -class ChatSettingsWidget : public BlockWidget { +class LabeledLink : public TWidget { public: - ChatSettingsWidget(QWidget *parent, UserData *self); + LabeledLink(QWidget *parent, const QString &label, const QString &text); + + void setLink(const QString &text); + + LinkButton *link() { + return _link; + } + + int naturalWidth() const override; protected: - // Resizes content and counts natural widget height for the desired width. int resizeGetHeight(int newWidth) override; private: - void refreshControls(); + ChildWidget _label; + ChildWidget _link; + +}; + +class ChatSettingsWidget : public BlockWidget { + Q_OBJECT + +public: + ChatSettingsWidget(QWidget *parent, UserData *self); + +private slots: + void onReplaceEmoji(); + void onViewList(); + void onDontAskDownloadPath(); + void onDownloadPath(); + void onSendByEnter(); + void onSendByCtrlEnter(); + void onAutomaticMediaDownloadSettings(); + void onManageStickerSets(); + +private: + void createControls(); + + ChildWidget _replaceEmoji = { nullptr }; + ChildWidget> _viewList = { nullptr }; + ChildWidget _dontAskDownloadPath = { nullptr }; + ChildWidget> _downloadPath = { nullptr }; + ChildWidget _sendByEnter = { nullptr }; + ChildWidget _sendByCtrlEnter = { nullptr }; + ChildWidget _automaticMediaDownloadSettings = { nullptr }; + ChildWidget _manageStickerSets = { nullptr }; }; diff --git a/Telegram/SourceFiles/settings/settings_fixed_bar.cpp b/Telegram/SourceFiles/settings/settings_fixed_bar.cpp index 7adeb6691..0c4615fa5 100644 --- a/Telegram/SourceFiles/settings/settings_fixed_bar.cpp +++ b/Telegram/SourceFiles/settings/settings_fixed_bar.cpp @@ -35,8 +35,8 @@ FixedBar::FixedBar(QWidget *parent) : TWidget(parent) }); } -void FixedBar::resizeToWidth(int newWidth) { - resize(newWidth, st::settingsFixedBarHeight); +int FixedBar::resizeGetHeight(int newWidth) { + return st::settingsFixedBarHeight; } void FixedBar::resizeEvent(QResizeEvent *e) { diff --git a/Telegram/SourceFiles/settings/settings_fixed_bar.h b/Telegram/SourceFiles/settings/settings_fixed_bar.h index 1e661586c..7ebc87e3d 100644 --- a/Telegram/SourceFiles/settings/settings_fixed_bar.h +++ b/Telegram/SourceFiles/settings/settings_fixed_bar.h @@ -30,12 +30,12 @@ class FixedBar : public TWidget { public: FixedBar(QWidget *parent); - void resizeToWidth(int newWidth); - protected: void resizeEvent(QResizeEvent *e) override; void paintEvent(QPaintEvent *e) override; + int resizeGetHeight(int newWidth) override; + private: ChildWidget _close; diff --git a/Telegram/SourceFiles/settings/settings_general_widget.cpp b/Telegram/SourceFiles/settings/settings_general_widget.cpp index b624cae16..2c3949a21 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_general_widget.cpp @@ -23,21 +23,180 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "ui/widgets/widget_slide_wrap.h" +#include "ui/flatbutton.h" +#include "ui/flatcheckbox.h" +#include "localstorage.h" +#include "pspecific.h" +#include "mainwindow.h" +#include "boxes/languagebox.h" +#include "boxes/confirmbox.h" +#include "ui/filedialog.h" +#include "langloaderplain.h" namespace Settings { +namespace { -GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_general)) { +QString currentVersion() { + auto result = QString::fromLatin1(AppVersionStr.c_str()); + if (cAlphaVersion()) { + result += " alpha"; + } + if (cBetaVersion()) { + result += qsl(" beta %1").arg(cBetaVersion()); + } + return result; +} + +} // namespace + +GeneralWidget::GeneralWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_general)) +, _changeLanguage(this, lang(lng_settings_change_lang)) { refreshControls(); } -void GeneralWidget::refreshControls() { +int GeneralWidget::resizeGetHeight(int newWidth) { + _changeLanguage->moveToRight(contentLeft(), st::settingsBlockMarginTop + st::settingsBlockTitleTop + st::settingsBlockTitleFont->ascent - st::btnDefLink.font->ascent); + return BlockWidget::resizeGetHeight(newWidth); } -int GeneralWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void GeneralWidget::refreshControls() { + style::margins marginSub(0, 0, 0, st::settingsSubSkip); + style::margins marginLarge(0, 0, 0, st::settingsLargeSkip); + style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); + style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2)); - newHeight += st::settingsBlockMarginBottom; - return newHeight; +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + addChildRow(_updateAutomatically, marginSub, lng_settings_update_automatically(lt_version, currentVersion()), SLOT(onUpdateAutomatically()), cAutoUpdate()); + style::margins marginLink(st::defaultCheckbox.textPosition.x(), 0, 0, st::settingsSkip); + addChildRow(_checkForUpdates, marginLink, lang(lng_settings_check_now), SLOT(onCheckForUpdates())); +#endif // TDESKTOP_DISABLE_AUTOUPDATE + + if (cPlatform() == dbipWindows || cSupportTray()) { + addChildRow(_enableTrayIcon, marginSmall, lang(lng_settings_workmode_tray), SLOT(onWorkmodeChange()), (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray)); + if (cPlatform() == dbipWindows) { + addChildRow(_enableTaskbarIcon, marginLarge, lang(lng_settings_workmode_window), SLOT(onWorkmodeChange()), (cWorkMode() == dbiwmWindowOnly || cWorkMode() == dbiwmWindowAndTray)); + + addChildRow(_autoStart, marginSmall, lang(lng_settings_auto_start), SLOT(onAutoStart()), cAutoStart()); + addChildRow(_startMinimized, marginLarge, slidedPadding, lang(lng_settings_start_min), SLOT(onStartMinimized()), cStartMinimized()); + if (!cAutoStart()) { + _startMinimized->hideFast(); + } + addChildRow(_addInSendTo, marginSmall, lang(lng_settings_add_sendto), SLOT(onAddInSendTo()), cSendToMenu()); + } + } +} + +void GeneralWidget::chooseCustomLang() { + auto filter = qsl("Language files (*.strings)"); + auto title = qsl("Choose language .strings file"); + + _chooseLangFileQueryId = FileDialog::queryReadFile(title, filter); +} + +void GeneralWidget::notifyFileQueryUpdated(const FileDialog::QueryUpdate &update) { + if (_chooseLangFileQueryId != update.queryId) { + return; + } + _chooseLangFileQueryId = 0; + + if (update.filePaths.isEmpty()) { + return; + } + + _testLanguage = QFileInfo(update.filePaths.front()).absoluteFilePath(); + LangLoaderPlain loader(_testLanguage, LangLoaderRequest(lng_sure_save_language, lng_cancel, lng_box_ok)); + if (loader.errors().isEmpty()) { + LangLoaderResult result = loader.found(); + QString text = result.value(lng_sure_save_language, langOriginal(lng_sure_save_language)), + save = result.value(lng_box_ok, langOriginal(lng_box_ok)), + cancel = result.value(lng_cancel, langOriginal(lng_cancel)); + auto box = new ConfirmBox(text, save, st::defaultBoxButton, cancel); + connect(box, SIGNAL(confirmed()), this, SLOT(onSaveTestLanguage())); + Ui::showLayer(box); + } else { + Ui::showLayer(new InformBox("Custom lang failed :(\n\nError: " + loader.errors())); + } +} + +void GeneralWidget::onChangeLanguage() { + if ((_changeLanguage->clickModifiers() & Qt::ShiftModifier) && (_changeLanguage->clickModifiers() & Qt::AltModifier)) { + chooseCustomLang(); + } else { + Ui::showLayer(new LanguageBox()); + } +} + +void GeneralWidget::onSaveTestLanguage() { + cSetLangFile(_testLanguage); + cSetLang(languageTest); + Local::writeSettings(); + cSetRestarting(true); + App::quit(); +} + +#ifndef TDESKTOP_DISABLE_AUTOUPDATE +void GeneralWidget::onUpdateAutomatically() { + +} + +void GeneralWidget::onCheckForUpdates() { + +} +#endif // TDESKTOP_DISABLE_AUTOUPDATE + +void GeneralWidget::onEnableTrayIcon() { + if ((!_enableTrayIcon->checked() || cPlatform() != dbipWindows) && !_enableTaskbarIcon->checked()) { + _enableTaskbarIcon->setChecked(true); + } else { + updateWorkmode(); + } +} + +void GeneralWidget::onEnableTaskbarIcon() { + if (!_enableTrayIcon->checked() && !_enableTaskbarIcon->checked()) { + _enableTrayIcon->setChecked(true); + } else { + updateWorkmode(); + } +} + +void GeneralWidget::updateWorkmode() { + DBIWorkMode newMode = (_enableTrayIcon->checked() && _enableTaskbarIcon->checked()) ? dbiwmWindowAndTray : (_enableTrayIcon->checked() ? dbiwmTrayOnly : dbiwmWindowOnly); + if (cWorkMode() != newMode && (newMode == dbiwmWindowAndTray || newMode == dbiwmTrayOnly)) { + cSetSeenTrayTooltip(false); + } + cSetWorkMode(newMode); + App::wnd()->psUpdateWorkmode(); + Local::writeSettings(); +} + +void GeneralWidget::onAutoStart() { + cSetAutoStart(_autoStart->checked()); + if (cAutoStart()) { + psAutoStart(true); + _startMinimized->slideDown(); + Local::writeSettings(); + } else { + psAutoStart(false); + if (_startMinimized->entity()->checked()) { + _startMinimized->entity()->setChecked(false); + } else { + Local::writeSettings(); + } + _startMinimized->slideUp(); + } +} + +void GeneralWidget::onStartMinimized() { + cSetStartMinimized(_startMinimized->entity()->checked()); + Local::writeSettings(); +} + +void GeneralWidget::onAddInSendTo() { + cSetSendToMenu(_addInSendTo->checked()); + psSendToMenu(_addInSendTo->checked()); + Local::writeSettings(); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_general_widget.h b/Telegram/SourceFiles/settings/settings_general_widget.h index af337f8b8..4778088d4 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.h +++ b/Telegram/SourceFiles/settings/settings_general_widget.h @@ -21,19 +21,62 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "settings/settings_block_widget.h" +#include "ui/filedialog.h" + +class Checkbox; +class LinkButton; + +namespace Ui { +template +class WidgetSlideWrap; +} // namespace Ui namespace Settings { class GeneralWidget : public BlockWidget { + Q_OBJECT + public: GeneralWidget(QWidget *parent, UserData *self); protected: - // Resizes content and counts natural widget height for the desired width. int resizeGetHeight(int newWidth) override; +private slots: + void onChangeLanguage(); + void onSaveTestLanguage(); + +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + void onUpdateAutomatically(); + void onCheckForUpdates(); +#endif // TDESKTOP_DISABLE_AUTOUPDATE + + void onEnableTrayIcon(); + void onEnableTaskbarIcon(); + + void onAutoStart(); + void onStartMinimized(); + void onAddInSendTo(); + private: void refreshControls(); + void updateWorkmode(); + void chooseCustomLang(); + void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update); + + ChildWidget _changeLanguage; +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + ChildWidget _updateAutomatically = { nullptr }; + ChildWidget _checkForUpdates = { nullptr }; +#endif // TDESKTOP_DISABLE_AUTOUPDATE + ChildWidget _enableTrayIcon = { nullptr }; + ChildWidget _enableTaskbarIcon = { nullptr }; + ChildWidget _autoStart = { nullptr }; + ChildWidget> _startMinimized = { nullptr }; + ChildWidget _addInSendTo = { nullptr }; + + FileDialog::QueryId _chooseLangFileQueryId = 0; + QString _testLanguage; }; diff --git a/Telegram/SourceFiles/settings/settings_info_widget.cpp b/Telegram/SourceFiles/settings/settings_info_widget.cpp index b7f17c04d..1510ca6d9 100644 --- a/Telegram/SourceFiles/settings/settings_info_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_info_widget.cpp @@ -23,21 +23,182 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "ui/flatlabel.h" +#include "ui/widgets/widget_slide_wrap.h" +#include "boxes/usernamebox.h" +#include "observer_peer.h" namespace Settings { +using UpdateFlag = Notify::PeerUpdate::Flag; + InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_info)) { + auto observeEvents = UpdateFlag::UsernameChanged | UpdateFlag::UserPhoneChanged; + Notify::registerPeerObserver(observeEvents, this, &InfoWidget::notifyPeerUpdated); + + createControls(); +} + +void InfoWidget::createControls() { + style::margins margin(0, -st::settingsBlockOneLineTextPart.margin.top(), 0, st::settingsSmallSkip - st::settingsBlockOneLineTextPart.margin.bottom()); + style::margins slidedPadding(0, st::settingsSmallSkip / 2, 0, st::settingsSmallSkip - (st::settingsSmallSkip / 2)); + addChildRow(_mobileNumber, margin, slidedPadding); + addChildRow(_username, margin, slidedPadding); + addChildRow(_link, margin, slidedPadding); refreshControls(); } void InfoWidget::refreshControls() { + refreshMobileNumber(); + refreshUsername(); + refreshLink(); } -int InfoWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void InfoWidget::refreshMobileNumber() { + TextWithEntities phoneText; + if (auto user = self()->asUser()) { + if (!user->phone().isEmpty()) { + phoneText.text = App::formatPhone(user->phone()); + } else { + phoneText.text = App::phoneFromSharedContact(peerToUser(user->id)); + } + } + setLabeledText(_mobileNumber, lang(lng_profile_mobile_number), phoneText, TextWithEntities(), lang(lng_profile_copy_phone)); +} - newHeight += st::settingsBlockMarginBottom; - return newHeight; +void InfoWidget::refreshUsername() { + TextWithEntities usernameText; + QString copyText; + if (self()->username.isEmpty()) { + usernameText.text = lang(lng_settings_choose_username); + } else { + usernameText.text = '@' + self()->username; + copyText = lang(lng_context_copy_mention); + } + usernameText.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, usernameText.text.size())); + setLabeledText(_username, lang(lng_profile_username), usernameText, TextWithEntities(), copyText); + if (auto text = _username->entity()->textLabel()) { + text->setClickHandlerHook(func(this, &InfoWidget::usernameClickHandlerHook)); + } +} + +void InfoWidget::refreshLink() { + TextWithEntities linkText; + TextWithEntities linkTextShort; + if (!self()->username.isEmpty()) { + linkText.text = qsl("https://telegram.me/") + self()->username; + linkText.entities.push_back(EntityInText(EntityInTextUrl, 0, linkText.text.size())); + linkTextShort.text = qsl("telegram.me/") + self()->username; + linkTextShort.entities.push_back(EntityInText(EntityInTextCustomUrl, 0, linkTextShort.text.size(), qsl("https://telegram.me/") + self()->username)); + } + setLabeledText(_link, lang(lng_profile_link), linkText, linkTextShort, QString()); + if (auto text = _link->entity()->textLabel()) { + text->setClickHandlerHook(func(this, &InfoWidget::usernameClickHandlerHook)); + } + if (auto shortText = _link->entity()->shortTextLabel()) { + shortText->setExpandLinksMode(ExpandLinksUrlOnly); + shortText->setClickHandlerHook(func(this, &InfoWidget::usernameClickHandlerHook)); + } +} + +bool InfoWidget::usernameClickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button) { + Ui::showLayer(new UsernameBox()); + return false; +} + +InfoWidget::LabeledWidget::LabeledWidget(QWidget *parent) : TWidget(parent) { + resize(width(), st::labelDefFlat.font->height); +} + +void InfoWidget::setLabeledText(ChildWidget &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) { + if (textWithEntities.text.isEmpty()) { + row->slideUp(); + } else { + row->entity()->setLabeledText(label, textWithEntities, shortTextWithEntities, copyText); + row->slideDown(); + } +} + +void InfoWidget::LabeledWidget::setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text) { + _label.destroy(); + _text.destroy(); + _shortText.destroy(); + if (textWithEntities.text.isEmpty()) return; + + _label = new FlatLabel(this, label, FlatLabel::InitType::Simple, st::settingsBlockLabel); + _label->show(); + setLabelText(_text, textWithEntities, copyText); + setLabelText(_shortText, shortTextWithEntities, copyText); +} + +void InfoWidget::LabeledWidget::setLabelText(ChildWidget &text, const TextWithEntities &textWithEntities, const QString ©Text) { + text.destroy(); + if (textWithEntities.text.isEmpty()) return; + + text = new FlatLabel(this, QString(), FlatLabel::InitType::Simple, st::settingsBlockOneLineTextPart); + text->show(); + text->setMarkedText(textWithEntities); + text->setContextCopyText(copyText); + text->setSelectable(true); + text->setDoubleClickSelectsParagraph(true); +} + +void InfoWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { + if (update.peer != self()) { + return; + } + + if (update.flags & UpdateFlag::UsernameChanged) { + refreshUsername(); + refreshLink(); + } + if (update.flags & (UpdateFlag::UserPhoneChanged)) { + refreshMobileNumber(); + } + + contentSizeUpdated(); +} + +int InfoWidget::LabeledWidget::naturalWidth() const { + if (!_text) return -1; + return _label->naturalWidth() + st::normalFont->spacew + (_shortText ? _shortText : _text)->naturalWidth(); +} + +int InfoWidget::LabeledWidget::resizeGetHeight(int newWidth) { + int marginLeft = st::settingsBlockOneLineTextPart.margin.left(); + int marginRight = st::settingsBlockOneLineTextPart.margin.right(); + + if (!_label) return 0; + + _label->moveToLeft(0, st::settingsBlockOneLineTextPart.margin.top()); + auto labelNatural = _label->naturalWidth(); + t_assert(labelNatural >= 0); + + _label->resize(qMin(newWidth, labelNatural), _label->height()); + + int textLeft = _label->width() + st::normalFont->spacew; + int textWidth = _text->naturalWidth(); + int availableWidth = newWidth - textLeft; + bool doesNotFit = (textWidth > availableWidth); + accumulate_min(textWidth, availableWidth); + accumulate_min(textWidth, st::msgMaxWidth); + if (textWidth + marginLeft + marginRight < 0) { + textWidth = -(marginLeft + marginRight); + } + _text->resizeToWidth(textWidth + marginLeft + marginRight); + _text->moveToLeft(textLeft - marginLeft, 0); + if (_shortText) { + _shortText->resizeToWidth(textWidth + marginLeft + marginRight); + _shortText->moveToLeft(textLeft - marginLeft, 0); + if (doesNotFit) { + _shortText->show(); + _text->hide(); + } else { + _shortText->hide(); + _text->show(); + } + } + return st::settingsBlockOneLineTextPart.margin.top() + _label->height() + st::settingsBlockOneLineTextPart.margin.bottom(); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_info_widget.h b/Telegram/SourceFiles/settings/settings_info_widget.h index b963a2601..6ffdc791d 100644 --- a/Telegram/SourceFiles/settings/settings_info_widget.h +++ b/Telegram/SourceFiles/settings/settings_info_widget.h @@ -34,30 +34,51 @@ class InfoWidget : public BlockWidget { public: InfoWidget(QWidget *parent, UserData *self); -protected: - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override; - private: // Observed notifications. void notifyPeerUpdated(const Notify::PeerUpdate &update); + bool usernameClickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button); + + void createControls(); void refreshControls(); void refreshMobileNumber(); void refreshUsername(); void refreshLink(); - // labelWidget may be nullptr. - void setLabeledText(ChildWidget *labelWidget, const QString &label, - ChildWidget *textWidget, const TextWithEntities &textWithEntities, const QString ©Text); + class LabeledWidget : public TWidget { + public: + LabeledWidget(QWidget *parent); - ChildWidget _mobileNumberLabel = { nullptr }; - ChildWidget _mobileNumber = { nullptr }; - ChildWidget _usernameLabel = { nullptr }; - ChildWidget _username = { nullptr }; - ChildWidget _linkLabel = { nullptr }; - ChildWidget _link = { nullptr }; - ChildWidget _linkShort = { nullptr }; + void setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text); + + FlatLabel *textLabel() { + return _text; + } + FlatLabel *shortTextLabel() { + return _shortText; + } + + int naturalWidth() const override; + + protected: + int resizeGetHeight(int newWidth) override; + + private: + void setLabelText(ChildWidget &text, const TextWithEntities &textWithEntities, const QString ©Text); + + ChildWidget _label = { nullptr }; + ChildWidget _text = { nullptr }; + ChildWidget _shortText = { nullptr }; + + }; + + using LabeledWrap = Ui::WidgetSlideWrap; + void setLabeledText(ChildWidget &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text); + + ChildWidget _mobileNumber = { nullptr }; + ChildWidget _username = { nullptr }; + ChildWidget _link = { nullptr }; }; diff --git a/Telegram/SourceFiles/settings/settings_inner_widget.cpp b/Telegram/SourceFiles/settings/settings_inner_widget.cpp index 4b600f6be..95763ed1b 100644 --- a/Telegram/SourceFiles/settings/settings_inner_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_inner_widget.cpp @@ -60,6 +60,9 @@ void InnerWidget::refreshBlocks() { _blocks.push_back(new Settings::PrivacyWidget(this, _self)); } _blocks.push_back(new Settings::AdvancedWidget(this, _self)); + for_const (auto block, _blocks) { + connect(block, SIGNAL(heightUpdated()), this, SLOT(onBlockHeightUpdated())); + } } void InnerWidget::showFinished() { @@ -68,32 +71,40 @@ void InnerWidget::showFinished() { } } -void InnerWidget::resizeToWidth(int newWidth, int contentLeft) { - int newHeight = resizeGetHeight(newWidth, contentLeft); - resize(newWidth, newHeight); +int InnerWidget::resizeGetHeight(int newWidth) { + if (_cover) { + _cover->setContentLeft(_contentLeft); + _cover->resizeToWidth(newWidth); + } + for_const (auto block, _blocks) { + block->setContentLeft(_contentLeft); + block->resizeToWidth(newWidth); + } + + int result = refreshBlocksPositions(); + return result; } -int InnerWidget::resizeGetHeight(int newWidth, int contentLeft) { - int result = 0; - if (_cover) { - _cover->setContentLeft(contentLeft); - _cover->resizeToWidth(newWidth); - result += _cover->height(); - } - result += st::settingsBlocksTop; +int InnerWidget::refreshBlocksPositions() { + int result = (_cover ? _cover->height() : 0) + st::settingsBlocksTop; for_const (auto block, _blocks) { if (block->isHidden()) { continue; } block->moveToLeft(0, result); - block->setContentLeft(contentLeft); - block->resizeToWidth(newWidth); result += block->height(); } return result; } +void InnerWidget::onBlockHeightUpdated() { + int newHeight = refreshBlocksPositions(); + if (newHeight != height()) { + resize(width(), newHeight); + } +} + void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) { _visibleTop = visibleTop; _visibleBottom = visibleBottom; diff --git a/Telegram/SourceFiles/settings/settings_inner_widget.h b/Telegram/SourceFiles/settings/settings_inner_widget.h index 658e3d47a..7f5453fcf 100644 --- a/Telegram/SourceFiles/settings/settings_inner_widget.h +++ b/Telegram/SourceFiles/settings/settings_inner_widget.h @@ -26,28 +26,42 @@ class CoverWidget; class BlockWidget; class InnerWidget : public TWidget { + Q_OBJECT + public: InnerWidget(QWidget *parent); // Count new height for width=newWidth and resize to it. - void resizeToWidth(int newWidth, int contentLeft); + void resizeToWidth(int newWidth, int contentLeft) { + _contentLeft = contentLeft; + return TWidget::resizeToWidth(newWidth); + } // Updates the area that is visible inside the scroll container. void setVisibleTopBottom(int visibleTop, int visibleBottom); void showFinished(); +private slots: + void onBlockHeightUpdated(); + +protected: + // Resizes content and counts natural widget height for the desired width. + int resizeGetHeight(int newWidth) override; + private: void refreshBlocks(); - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth, int contentLeft); + // Returns the new height value. + int refreshBlocksPositions(); ChildWidget _cover = { nullptr }; QList _blocks; UserData *_self = nullptr; + int _contentLeft = 0; + int _visibleTop = 0; int _visibleBottom = 0; diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index bfa5a108c..93a3ce4c4 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -23,21 +23,105 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "localstorage.h" +#include "ui/widgets/widget_slide_wrap.h" +#include "ui/flatcheckbox.h" +#include "mainwindow.h" namespace Settings { NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_notify)) { - refreshControls(); + createControls(); } -void NotificationsWidget::refreshControls() { +void NotificationsWidget::createControls() { + style::margins margin(0, 0, 0, st::settingsSmallSkip); + style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2)); + addChildRow(_desktopNotifications, margin, lang(lng_settings_desktop_notify), SLOT(onDesktopNotifications()), cDesktopNotify()); + addChildRow(_showSenderName, margin, slidedPadding, lang(lng_settings_show_name), SLOT(onShowSenderName()), cNotifyView() <= dbinvShowName); + addChildRow(_showMessagePreview, margin, slidedPadding, lang(lng_settings_show_preview), SLOT(onShowMessagePreview()), cNotifyView() <= dbinvShowPreview); + if (!_showSenderName->entity()->checked()) { + _showMessagePreview->hideFast(); + } + if (!_desktopNotifications->checked()) { + _showSenderName->hideFast(); + _showMessagePreview->hideFast(); + } +#ifdef Q_OS_WIN + if (App::wnd()->psHasNativeNotifications()) { + addChildRow(_windowsNative, margin, lang(lng_settings_use_windows), SLOT(onWindowsNative()), cWindowsNotifications()); + } +#endif // Q_OS_WIN + addChildRow(_playSound, margin, lang(lng_settings_sound_notify), SLOT(onPlaySound()), cSoundNotify()); + addChildRow(_includeMuted, margin, lang(lng_settings_include_muted), SLOT(onIncludeMuted()), cIncludeMuted()); } -int NotificationsWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void NotificationsWidget::onDesktopNotifications() { + cSetDesktopNotify(_desktopNotifications->checked()); + Local::writeUserSettings(); + if (App::wnd()) App::wnd()->updateTrayMenu(); - newHeight += st::settingsBlockMarginBottom; - return newHeight; + if (_desktopNotifications->checked()) { + _showSenderName->slideDown(); + if (_showSenderName->entity()->checked()) { + _showMessagePreview->slideDown(); + } + } else { + App::wnd()->notifyClear(); + _showSenderName->slideUp(); + _showMessagePreview->slideUp(); + } +} + +void NotificationsWidget::onShowSenderName() { + if (_showSenderName->entity()->checked()) { + _showMessagePreview->slideDown(); + } else { + _showMessagePreview->slideUp(); + } + + if (!_showSenderName->entity()->checked()) { + cSetNotifyView(dbinvShowNothing); + } else if (!_showMessagePreview->entity()->checked()) { + cSetNotifyView(dbinvShowName); + } else { + cSetNotifyView(dbinvShowPreview); + } + Local::writeUserSettings(); + App::wnd()->notifyUpdateAll(); +} + +void NotificationsWidget::onShowMessagePreview() { + if (_showMessagePreview->entity()->checked()) { + cSetNotifyView(dbinvShowPreview); + } else if (_showSenderName->entity()->checked()) { + cSetNotifyView(dbinvShowName); + } else { + cSetNotifyView(dbinvShowNothing); + } + Local::writeUserSettings(); + App::wnd()->notifyUpdateAll(); +} + +#ifdef Q_OS_WIN +void NotificationsWidget::onWindowsNative() { + if (cPlatform() != dbipWindows) return; + cSetWindowsNotifications(!cWindowsNotifications()); + App::wnd()->notifyClearFast(); + cSetCustomNotifies(!cWindowsNotifications()); + Local::writeUserSettings(); +} +#endif // Q_OS_WIN + +void NotificationsWidget::onPlaySound() { + cSetSoundNotify(_playSound->checked()); + Local::writeUserSettings(); +} + +void NotificationsWidget::onIncludeMuted() { + cSetIncludeMuted(_includeMuted->checked()); + Notify::unreadCounterUpdated(); + Local::writeUserSettings(); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.h b/Telegram/SourceFiles/settings/settings_notifications_widget.h index 502f338b0..77d61e735 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.h +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.h @@ -25,15 +25,30 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Settings { class NotificationsWidget : public BlockWidget { + Q_OBJECT + public: NotificationsWidget(QWidget *parent, UserData *self); -protected: - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override; +private slots: + void onDesktopNotifications(); + void onShowSenderName(); + void onShowMessagePreview(); +#ifdef Q_OS_WIN + void onWindowsNative(); +#endif // Q_OS_WIN + void onPlaySound(); + void onIncludeMuted(); private: - void refreshControls(); + void createControls(); + + ChildWidget _desktopNotifications = { nullptr }; + ChildWidget> _showSenderName = { nullptr }; + ChildWidget> _showMessagePreview = { nullptr }; + ChildWidget _windowsNative = { nullptr }; + ChildWidget _playSound = { nullptr }; + ChildWidget _includeMuted = { nullptr }; }; diff --git a/Telegram/SourceFiles/settings/settings_privacy_widget.cpp b/Telegram/SourceFiles/settings/settings_privacy_widget.cpp index 91933504f..3303cd7c0 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_widget.cpp @@ -31,13 +31,25 @@ PrivacyWidget::PrivacyWidget(QWidget *parent, UserData *self) : BlockWidget(pare } void PrivacyWidget::refreshControls() { + style::margins marginSmall(0, 0, 0, st::settingsSmallSkip); + style::margins marginSkip(0, 0, 0, st::settingsSkip); + style::margins slidedPadding(0, marginSmall.bottom() / 2, 0, marginSmall.bottom() - (marginSmall.bottom() / 2)); + + addChildRow(_editPasscode, marginSmall, lang(lng_passcode_turn_on), SLOT(onEditPasscode())); + addChildRow(_editPassword, marginSmall, lang(lng_cloud_password_set), SLOT(onEditPassword())); + addChildRow(_showAllSessions, marginSmall, lang(lng_settings_show_sessions), SLOT(onShowSessions())); } -int PrivacyWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void PrivacyWidget::onEditPasscode() { + +} + +void PrivacyWidget::onEditPassword() { + +} + +void PrivacyWidget::onShowSessions() { - newHeight += st::settingsBlockMarginBottom; - return newHeight; } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_privacy_widget.h b/Telegram/SourceFiles/settings/settings_privacy_widget.h index 256a882a8..7ae26b91e 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_widget.h +++ b/Telegram/SourceFiles/settings/settings_privacy_widget.h @@ -25,16 +25,23 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Settings { class PrivacyWidget : public BlockWidget { + Q_OBJECT + public: PrivacyWidget(QWidget *parent, UserData *self); -protected: - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override; +private slots: + void onEditPasscode(); + void onEditPassword(); + void onShowSessions(); private: void refreshControls(); + ChildWidget _editPasscode = { nullptr }; + ChildWidget _editPassword = { nullptr }; + ChildWidget _showAllSessions = { nullptr }; + }; } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.cpp b/Telegram/SourceFiles/settings/settings_scale_widget.cpp index 849951b33..7660e5050 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_scale_widget.cpp @@ -23,21 +23,244 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_settings.h" #include "lang.h" +#include "localstorage.h" +#include "mainwindow.h" +#include "boxes/confirmbox.h" +#include "application.h" namespace Settings { +namespace { + +QString scaleLabel(DBIScale scale) { + switch (scale) { + case dbisOne: return qsl("100%"); + case dbisOneAndQuarter: return qsl("125%"); + case dbisOneAndHalf: return qsl("150%"); + case dbisTwo: return qsl("200%"); + } + return QString(); +} + +} // namespace + +Slider::Slider(QWidget *parent) : TWidget(parent) +, _a_left(animation(this, &Slider::step_left)) { + setCursor(style::cur_pointer); +} + +void Slider::setActiveSection(int index) { + setSelectedSection(index); + if (_activeIndex != index) { + _activeIndex = index; + emit sectionActivated(); + } +} + +void Slider::setActiveSectionFast(int index) { + setActiveSection(index); + a_left.finish(); + _a_left.stop(); + update(); +} + +void Slider::addSection(const QString &label) { + auto section = Section(label); + _sections.push_back(section); +} + +void Slider::resizeSections(int newWidth) { + auto count = _sections.size(); + if (!count) return; + + auto skips = count - 1; + auto sectionsWidth = newWidth - skips * st::settingsSliderSkip; + auto sectionWidth = sectionsWidth / float64(count); + auto x = 0.; + for (int i = 0; i != count; ++i) { + auto §ion = _sections[i]; + auto skip = i * st::settingsSliderThickness; + section.left = qFloor(x) + skip; + x += sectionWidth; + section.width = qRound(x) - (section.left - skip); + } + a_left = anim::ivalue(_sections[_activeIndex].left, _sections[_activeIndex].left); + _a_left.stop(); +} + +void Slider::mousePressEvent(QMouseEvent *e) { + setSelectedSection(getIndexFromPosition(e->pos())); + _pressed = true; +} + +void Slider::mouseMoveEvent(QMouseEvent *e) { + if (!_pressed) return; + setSelectedSection(getIndexFromPosition(e->pos())); +} + +void Slider::mouseReleaseEvent(QMouseEvent *e) { + if (!_pressed) return; + _pressed = false; + setActiveSection(getIndexFromPosition(e->pos())); +} + +void Slider::setSelectedSection(int index) { + if (index < 0) return; + + if (_selected != index) { + _selected = index; + a_left.start(_sections[_selected].left); + _a_left.start(); + } +} + +void Slider::paintEvent(QPaintEvent *e) { + Painter p(this); + + int activeLeft = a_left.current(); + + p.setFont(st::settingsSliderLabelFont); + p.setPen(st::settingsSliderLabelFg); + for (int i = 0, count = _sections.size(); i != count; ++i) { + auto §ion = _sections.at(i); + auto from = section.left, tofill = section.width; + if (activeLeft > from) { + auto fill = qMin(tofill, activeLeft - from); + p.fillRect(myrtlrect(from, st::settingsSliderTop, fill, st::settingsSliderThickness), st::settingsSliderInactiveFg); + from += fill; + tofill -= fill; + } + if (activeLeft + section.width > from) { + if (auto fill = qMin(tofill, activeLeft + section.width - from)) { + p.fillRect(myrtlrect(from, st::settingsSliderTop, fill, st::settingsSliderThickness), st::settingsSliderActiveFg); + from += fill; + tofill -= fill; + } + } + if (tofill) { + p.fillRect(myrtlrect(from, st::settingsSliderTop, tofill, st::settingsSliderThickness), st::settingsSliderInactiveFg); + } + p.drawTextLeft(section.left + (section.width - section.labelWidth) / 2, st::settingsSliderLabelTop, width(), section.label, section.labelWidth); + } +} + +int Slider::resizeGetHeight(int newWidth) { + resizeSections(newWidth); + return st::settingsSliderHeight; +} + +int Slider::getIndexFromPosition(QPoint pos) { + int count = _sections.size(); + for (int i = 0; i != count; ++i) { + if (_sections[i].left + _sections[i].width > pos.x()) { + return i; + } + } + return count - 1; +} + +void Slider::step_left(float64 ms, bool timer) { + auto dt = ms / st::settingsSliderDuration; + if (dt >= 1) { + a_left.finish(); + _a_left.stop(); + } else { + a_left.update(dt, anim::linear); + } + if (timer) { + update(); + } +} + +Slider::Section::Section(const QString &label) +: label(label) +, labelWidth(st::settingsSliderLabelFont->width(label)) { +} ScaleWidget::ScaleWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_scale)) { - refreshControls(); + createControls(); } -void ScaleWidget::refreshControls() { +void ScaleWidget::createControls() { + style::margins margin(0, 0, 0, st::settingsSmallSkip); + + addChildRow(_auto, margin, lng_settings_scale_auto(lt_cur, scaleLabel(cScreenScale())), SLOT(onAutoChosen()), (cConfigScale() == dbisAuto)); + addChildRow(_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); + + connect(_scale, SIGNAL(sectionActivated()), this, SLOT(onSectionActivated())); } -int ScaleWidget::resizeGetHeight(int newWidth) { - int newHeight = contentTop(); +void ScaleWidget::onAutoChosen() { + auto newScale = _auto->checked() ? dbisAuto : cEvalScale(cConfigScale()); + if (newScale == cScreenScale()) { + if (newScale != cScale()) { + newScale = cScale(); + } else { + switch (newScale) { + case dbisOne: newScale = dbisOneAndQuarter; break; + case dbisOneAndQuarter: newScale = dbisOne; break; + case dbisOneAndHalf: newScale = dbisOneAndQuarter; break; + case dbisTwo: newScale = dbisOneAndHalf; break; + } + } + } + setScale(newScale); +} - newHeight += st::settingsBlockMarginBottom; - return newHeight; +void ScaleWidget::setScale(DBIScale newScale) { + if (cConfigScale() == newScale) return; + + cSetConfigScale(newScale); + Local::writeSettings(); + App::wnd()->getTitle()->showUpdateBtn(); + if (newScale == dbisAuto && !_auto->checked()) { + _auto->setChecked(true); + } else if (newScale != dbisAuto && _auto->checked()) { + _auto->setChecked(false); + } + if (newScale == dbisAuto) newScale = cScreenScale(); + if (_scale->activeSection() != newScale - 1) { + _scale->setActiveSection(newScale - 1); + } + if (cEvalScale(cConfigScale()) != cEvalScale(cRealScale())) { + auto box = new ConfirmBox(lang(lng_settings_need_restart), lang(lng_settings_restart_now), st::defaultBoxButton, lang(lng_settings_restart_later)); + connect(box, SIGNAL(confirmed()), this, SLOT(onRestartNow())); + Ui::showLayer(box); + } +} + +void ScaleWidget::onSectionActivated() { + auto newScale = dbisAuto; + switch (_scale->activeSection()) { + case 0: newScale = dbisOne; break; + case 1: newScale = dbisOneAndQuarter; break; + case 2: newScale = dbisOneAndHalf; break; + case 3: newScale = dbisTwo; break; + } + if (newScale == cScreenScale()) { + newScale = dbisAuto; + } + setScale(newScale); +} + +void ScaleWidget::onRestartNow() { +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + bool updateReady = (Sandbox::updatingState() == Application::UpdatingReady); +#else + bool updateReady = false; +#endif + if (updateReady) { + cSetRestartingUpdate(true); + } else { + cSetRestarting(true); + cSetRestartingToSettings(true); + } + App::quit(); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.h b/Telegram/SourceFiles/settings/settings_scale_widget.h index a36ee7552..1a4485c45 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.h +++ b/Telegram/SourceFiles/settings/settings_scale_widget.h @@ -22,18 +22,74 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "settings/settings_block_widget.h" +class Checkbox; + namespace Settings { +class Slider : public TWidget { + Q_OBJECT + +public: + Slider(QWidget *parent); + + int activeSection() const { + return _activeIndex; + } + void setActiveSection(int index); + void setActiveSectionFast(int index); + void addSection(const QString &label); + +protected: + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + + int resizeGetHeight(int newWidth) override; + +signals: + void sectionActivated(); + +private: + void resizeSections(int newWidth); + int getIndexFromPosition(QPoint pos); + void setSelectedSection(int index); + void step_left(float64 ms, bool timer); + + struct Section { + Section(const QString &label); + + int left, width; + QString label; + int labelWidth; + }; + QList
_sections; + int _activeIndex = 0; + + bool _pressed = false; + int _selected = 0; + anim::ivalue a_left = { 0 }; + Animation _a_left; + +}; + class ScaleWidget : public BlockWidget { + Q_OBJECT + public: ScaleWidget(QWidget *parent, UserData *self); -protected: - // Resizes content and counts natural widget height for the desired width. - int resizeGetHeight(int newWidth) override; +private slots: + void onAutoChosen(); + void onSectionActivated(); + void onRestartNow(); private: - void refreshControls(); + void createControls(); + void setScale(DBIScale newScale); + + ChildWidget _auto = { nullptr }; + ChildWidget _scale = { nullptr }; }; diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index 8dca3ec10..8d57e058f 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -137,7 +137,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent) // general , _changeLanguage(this, lang(lng_settings_change_lang)) #ifndef TDESKTOP_DISABLE_AUTOUPDATE -, _autoUpdate(this, lang(lng_settings_auto_update), cAutoUpdate()) +, _autoUpdate(this, QString(), cAutoUpdate()) , _checkNow(this, lang(lng_settings_check_now)) , _restartNow(this, lang(lng_settings_update_now)) #endif @@ -672,7 +672,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { // advanced p.setFont(st::setHeaderFont->f); p.setPen(st::setHeaderColor->p); - p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced)); + p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced_settings)); top += st::setHeaderSkip; p.setFont(st::linkFont->f); diff --git a/Telegram/SourceFiles/ui/buttons/left_outline_button.cpp b/Telegram/SourceFiles/ui/buttons/left_outline_button.cpp index 8fe30b500..04d94a4b2 100644 --- a/Telegram/SourceFiles/ui/buttons/left_outline_button.cpp +++ b/Telegram/SourceFiles/ui/buttons/left_outline_button.cpp @@ -42,13 +42,13 @@ void LeftOutlineButton::setText(const QString &text) { update(); } -void LeftOutlineButton::resizeToWidth(int newWidth) { +int LeftOutlineButton::resizeGetHeight(int newWidth) { int availableWidth = qMax(newWidth - _st.padding.left() - _st.padding.right(), 1); if ((availableWidth < _fullTextWidth) || (_textWidth < availableWidth)) { _text = _st.font->elided(_fullText, availableWidth); _textWidth = _st.font->width(_text); } - resize(newWidth, _st.padding.top() + _st.font->height + _st.padding.bottom()); + return _st.padding.top() + _st.font->height + _st.padding.bottom(); } void LeftOutlineButton::paintEvent(QPaintEvent *e) { diff --git a/Telegram/SourceFiles/ui/buttons/left_outline_button.h b/Telegram/SourceFiles/ui/buttons/left_outline_button.h index 81aee2416..011b4c2ad 100644 --- a/Telegram/SourceFiles/ui/buttons/left_outline_button.h +++ b/Telegram/SourceFiles/ui/buttons/left_outline_button.h @@ -28,7 +28,6 @@ class LeftOutlineButton : public Button { public: LeftOutlineButton(QWidget *parent, const QString &text, const style::OutlineButton &st = st::defaultLeftOutlineButton); - void resizeToWidth(int newWidth); void setText(const QString &text); protected: @@ -36,6 +35,8 @@ protected: void onStateChanged(int oldState, ButtonStateChangeSource source) override; + int resizeGetHeight(int newWidth) override; + private: QString _text, _fullText; int _textWidth, _fullTextWidth; diff --git a/Telegram/SourceFiles/ui/flatbutton.cpp b/Telegram/SourceFiles/ui/flatbutton.cpp index df5a762be..2fff65d45 100644 --- a/Telegram/SourceFiles/ui/flatbutton.cpp +++ b/Telegram/SourceFiles/ui/flatbutton.cpp @@ -127,6 +127,10 @@ LinkButton::LinkButton(QWidget *parent, const QString &text, const style::linkBu setCursor(style::cur_pointer); } +int LinkButton::naturalWidth() const { + return _st.font->width(_text); +} + void LinkButton::paintEvent(QPaintEvent *e) { QPainter p(this); p.setFont(((_state & StateOver) ? _st.overFont : _st.font)->f); diff --git a/Telegram/SourceFiles/ui/flatbutton.h b/Telegram/SourceFiles/ui/flatbutton.h index 39e3a5f6b..aada3d54c 100644 --- a/Telegram/SourceFiles/ui/flatbutton.h +++ b/Telegram/SourceFiles/ui/flatbutton.h @@ -66,23 +66,24 @@ class LinkButton : public Button { Q_OBJECT public: - LinkButton(QWidget *parent, const QString &text, const style::linkButton &st = st::btnDefLink); - void paintEvent(QPaintEvent *e); + int naturalWidth() const override; void setText(const QString &text); ~LinkButton(); -public slots: +protected: + void paintEvent(QPaintEvent *e) override; +public slots: void onStateChange(int oldState, ButtonStateChangeSource source); private: - QString _text; style::linkButton _st; + }; class IconedButton : public Button { diff --git a/Telegram/SourceFiles/ui/flatcheckbox.cpp b/Telegram/SourceFiles/ui/flatcheckbox.cpp index 631a484b9..ba03450a7 100644 --- a/Telegram/SourceFiles/ui/flatcheckbox.cpp +++ b/Telegram/SourceFiles/ui/flatcheckbox.cpp @@ -310,6 +310,10 @@ void Checkbox::step_checked(float64 ms, bool timer) { if (timer) update(_checkRect); } +int Checkbox::naturalWidth() const { + return _st.textPosition.x() + _st.font->width(_fullText); +} + void Checkbox::paintEvent(QPaintEvent *e) { Painter p(this); diff --git a/Telegram/SourceFiles/ui/flatcheckbox.h b/Telegram/SourceFiles/ui/flatcheckbox.h index 6ec4d9c36..64d59c24b 100644 --- a/Telegram/SourceFiles/ui/flatcheckbox.h +++ b/Telegram/SourceFiles/ui/flatcheckbox.h @@ -98,7 +98,10 @@ public: void finishAnimations(); - void paintEvent(QPaintEvent *e); + int naturalWidth() const override; + +protected: + void paintEvent(QPaintEvent *e) override; public slots: void onClicked(); diff --git a/Telegram/SourceFiles/ui/flatlabel.cpp b/Telegram/SourceFiles/ui/flatlabel.cpp index 94ce3882c..e879861d5 100644 --- a/Telegram/SourceFiles/ui/flatlabel.cpp +++ b/Telegram/SourceFiles/ui/flatlabel.cpp @@ -112,11 +112,13 @@ void FlatLabel::setBreakEverywhere(bool breakEverywhere) { _breakEverywhere = breakEverywhere; } -void FlatLabel::resizeToWidth(int32 width) { +int FlatLabel::resizeGetHeight(int newWidth) { + _allowedWidth = newWidth; textstyleSet(&_tst); - _allowedWidth = width; - refreshSize(); + int textWidth = countTextWidth(); + int textHeight = countTextHeight(textWidth); textstyleRestore(); + return _st.margin.top() + textHeight + _st.margin.bottom(); } int FlatLabel::naturalWidth() const { diff --git a/Telegram/SourceFiles/ui/flatlabel.h b/Telegram/SourceFiles/ui/flatlabel.h index 94b1ec88e..978622b79 100644 --- a/Telegram/SourceFiles/ui/flatlabel.h +++ b/Telegram/SourceFiles/ui/flatlabel.h @@ -43,8 +43,7 @@ public: void setExpandLinksMode(ExpandLinksMode mode); void setBreakEverywhere(bool breakEverywhere); - void resizeToWidth(int32 width); - int naturalWidth() const; + int naturalWidth() const override; void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk); @@ -70,6 +69,8 @@ protected: bool event(QEvent *e) override; // calls touchEvent when necessary void touchEvent(QTouchEvent *e); + int resizeGetHeight(int newWidth) override; + private slots: void onCopySelectedText(); void onCopyContextText(); diff --git a/Telegram/SourceFiles/ui/scrollarea.h b/Telegram/SourceFiles/ui/scrollarea.h index 524811308..7ea0bd0ac 100644 --- a/Telegram/SourceFiles/ui/scrollarea.h +++ b/Telegram/SourceFiles/ui/scrollarea.h @@ -276,21 +276,10 @@ public: ScrolledWidget(QWidget *parent = nullptr) : TWidget(parent) { } - // Count new height for width=newWidth and resize to it. - void resizeToWidth(int newWidth) { - resize(newWidth, resizeGetHeight(newWidth)); - } - // Updates the area that is visible inside the scroll container. virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) { } -protected: - // Resizes content and counts natural widget height for the desired width. - virtual int resizeGetHeight(int newWidth) { - return height(); - } - signals: void heightUpdated(); diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h index 7b6c12261..22046e348 100644 --- a/Telegram/SourceFiles/ui/twidget.h +++ b/Telegram/SourceFiles/ui/twidget.h @@ -206,7 +206,19 @@ public: return QPointer(this); } - virtual ~TWidget() { + // Get the size of the widget as it should be. + // Negative return value means no default width. + virtual int naturalWidth() const { + return -1; + } + + // Count new height for width=newWidth and resize to it. + void resizeToWidth(int newWidth) { + auto newSize = QSize(newWidth, resizeGetHeight(newWidth)); + if (newSize != size()) { + resize(newSize); + update(); + } } protected: @@ -217,6 +229,11 @@ protected: return QWidget::leaveEvent(e); } + // Resizes content and counts natural widget height for the desired width. + virtual int resizeGetHeight(int newWidth) { + return height(); + } + }; void myEnsureResized(QWidget *target); diff --git a/Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h b/Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h new file mode 100644 index 000000000..55cf18c2d --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h @@ -0,0 +1,164 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "styles/style_widgets.h" + +namespace Ui { + +template +class WidgetSlideWrap : public TWidget { +public: + WidgetSlideWrap(QWidget *parent, Widget *entity + , style::margins entityPadding + , base::lambda_unique &&updateCallback + , int duration = st::widgetSlideDuration) : TWidget(parent) + , _entity(entity) + , _padding(entityPadding) + , _duration(duration) + , _updateCallback(std_::move(updateCallback)) + , _a_height(animation(this, &WidgetSlideWrap::step_height)) { + entity->setParent(this); + entity->moveToLeft(_padding.left(), _padding.top()); + _realSize = entity->rect().marginsAdded(_padding).size(); + entity->installEventFilter(this); + resize(_realSize); + } + + bool eventFilter(QObject *object, QEvent *event) { + if (object == _entity && event->type() == QEvent::Resize) { + _realSize = _entity->rect().marginsAdded(_padding).size(); + if (!_inResizeToWidth) { + resize(_realSize.width(), (_forceHeight >= 0) ? _forceHeight : _realSize.height()); + if (_updateCallback) { + _updateCallback(); + } + } + } + return TWidget::eventFilter(object, event); + } + + void slideUp() { + if (isHidden()) { + _forceHeight = 0; + resize(_realSize.width(), _forceHeight); + if (_updateCallback) _updateCallback(); + return; + } + if (_a_height.animating()) { + if (_hiding) return; + } else { + a_height = anim::ivalue(_realSize.height()); + } + a_height.start(0); + _hiding = true; + _a_height.start(); + } + + void slideDown() { + if (isHidden()) { + show(); + } + if (_forceHeight < 0) { + return; + } + + if (_a_height.animating()) { + if (!_hiding) return; + } + a_height.start(_realSize.height()); + _forceHeight = a_height.current(); + _hiding = false; + _a_height.start(); + } + + void showFast() { + _a_height.stop(); + resize(_realSize); + if (_updateCallback) { + _updateCallback(); + } + } + + void hideFast() { + _a_height.stop(); + a_height = anim::ivalue(0); + _forceHeight = 0; + resize(_realSize.width(), 0); + hide(); + if (_updateCallback) { + _updateCallback(); + } + } + + Widget *entity() { + return _entity; + } + + const Widget *entity() const { + return _entity; + } + + int naturalWidth() const override { + return _padding.top() + _entity->naturalWidth() + _padding.bottom(); + } + +protected: + int resizeGetHeight(int newWidth) override { + _inResizeToWidth = true; + _entity->resizeToWidth(newWidth - _padding.left() - _padding.right()); + _inResizeToWidth = false; + return (_forceHeight >= 0) ? _forceHeight : _realSize.height(); + } + +private: + void step_height(float64 ms, bool timer) { + auto dt = ms / _duration; + if (dt >= 1) { + a_height.finish(); + _a_height.stop(); + _forceHeight = _hiding ? 0 : -1; + if (_hiding) hide(); + } else { + a_height.update(dt, anim::linear); + _forceHeight = a_height.current(); + } + resize(_realSize.width(), (_forceHeight >= 0) ? _forceHeight : _realSize.height()); + if (_updateCallback) { + _updateCallback(); + } + } + + Widget *_entity; + bool _inResizeToWidth = false; + style::margins _padding; + int _duration; + base::lambda_unique _updateCallback; + + style::size _realSize; + int _forceHeight = -1; + anim::ivalue a_height; + Animation _a_height; + bool _hiding = false; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style index 9b9af8124..53f5e17d6 100644 --- a/Telegram/SourceFiles/ui/widgets/widgets.style +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -32,3 +32,5 @@ defaultLabelSimple: LabelSimple { maxWidth: 0px; textFg: windowTextFg; } + +widgetSlideDuration: 200; diff --git a/Telegram/build/version b/Telegram/build/version index cfe823ff8..329387da5 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -2,5 +2,5 @@ AppVersion 10002 AppVersionStrMajor 0.10 AppVersionStrSmall 0.10.2 AppVersionStr 0.10.2 -AlphaChannel 1 -BetaVersion 0 +AlphaChannel 0 +BetaVersion 10002001 diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index cbf8f386d..56d8947e5 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -394,6 +394,7 @@ '<(src_loc)/ui/toast/toast_widget.h', '<(src_loc)/ui/widgets/label_simple.cpp', '<(src_loc)/ui/widgets/label_simple.h', + '<(src_loc)/ui/widgets/widget_slide_wrap.h', '<(src_loc)/ui/animation.cpp', '<(src_loc)/ui/animation.h', '<(src_loc)/ui/boxshadow.cpp',