mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 18:21:42 -05:00
Most of the new Settings sections filled with widgets.
Some animations added: new scale slider, widget_slide_wrap<TWidget>. Any TWidget now can resizeToWidth() with overriden resizeGetHeight().
This commit is contained in:
parent
b9e22f59a1
commit
993b91ac15
50 changed files with 1516 additions and 181 deletions
|
@ -253,7 +253,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_settings_change_lang" = "Change language";
|
"lng_settings_change_lang" = "Change language";
|
||||||
"lng_languages" = "Languages";
|
"lng_languages" = "Languages";
|
||||||
"lng_sure_save_language" = "Telegram will restart in order to change language";
|
"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_current_version" = "Version {version}";
|
||||||
"lng_settings_check_now" = "Check for updates";
|
"lng_settings_check_now" = "Check for updates";
|
||||||
"lng_settings_update_checking" = "Checking 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_cleared" = "Cleared!";
|
||||||
"lng_local_storage_clear_failed" = "Clear failed :(";
|
"lng_local_storage_clear_failed" = "Clear failed :(";
|
||||||
|
|
||||||
"lng_settings_section_advanced" = "Advanced";
|
"lng_settings_section_advanced_settings" = "Advanced Settings";
|
||||||
|
|
||||||
"lng_passcode_remove_button" = "Remove";
|
"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_one_sure" = "Do you want to terminate this session?";
|
||||||
"lng_settings_reset_button" = "Terminate";
|
"lng_settings_reset_button" = "Terminate";
|
||||||
"lng_settings_reset_done" = "Other sessions terminated";
|
"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_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_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";
|
"lng_settings_faq_button" = "Go to FAQ";
|
||||||
|
|
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,10,2,0
|
FILEVERSION 0,10,2,1
|
||||||
PRODUCTVERSION 0,10,2,0
|
PRODUCTVERSION 0,10,2,1
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.10.2.0"
|
VALUE "FileVersion", "0.10.2.1"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.10.2.0"
|
VALUE "ProductVersion", "0.10.2.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,10,2,0
|
FILEVERSION 0,10,2,1
|
||||||
PRODUCTVERSION 0,10,2,0
|
PRODUCTVERSION 0,10,2,1
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,10 +43,10 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileDescription", "Telegram Updater"
|
VALUE "FileDescription", "Telegram Updater"
|
||||||
VALUE "FileVersion", "0.10.2.0"
|
VALUE "FileVersion", "0.10.2.1"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.10.2.0"
|
VALUE "ProductVersion", "0.10.2.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -22,9 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/basic_types.h"
|
#include "core/basic_types.h"
|
||||||
|
|
||||||
#define BETA_VERSION_MACRO (0ULL)
|
#define BETA_VERSION_MACRO (10002001ULL)
|
||||||
|
|
||||||
constexpr int AppVersion = 10002;
|
constexpr int AppVersion = 10002;
|
||||||
constexpr str_const AppVersionStr = "0.10.2";
|
constexpr str_const AppVersionStr = "0.10.2";
|
||||||
constexpr bool AppAlphaVersion = true;
|
constexpr bool AppAlphaVersion = false;
|
||||||
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
|
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
|
||||||
|
|
|
@ -2557,9 +2557,7 @@ bool BotKeyboard::forceReply() const {
|
||||||
return _forceReply;
|
return _forceReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotKeyboard::resizeToWidth(int newWidth, int maxOuterHeight) {
|
int BotKeyboard::resizeGetHeight(int newWidth) {
|
||||||
_maxOuterHeight = maxOuterHeight;
|
|
||||||
|
|
||||||
updateStyle(newWidth);
|
updateStyle(newWidth);
|
||||||
_height = st::botKbScroll.deltat + st::botKbScroll.deltab + (_impl ? _impl->naturalHeight() : 0);
|
_height = st::botKbScroll.deltat + st::botKbScroll.deltab + (_impl ? _impl->naturalHeight() : 0);
|
||||||
if (_maximizeSize) {
|
if (_maximizeSize) {
|
||||||
|
@ -2570,10 +2568,7 @@ void BotKeyboard::resizeToWidth(int newWidth, int maxOuterHeight) {
|
||||||
int implHeight = _height - (st::botKbScroll.deltat + st::botKbScroll.deltab);
|
int implHeight = _height - (st::botKbScroll.deltat + st::botKbScroll.deltab);
|
||||||
_impl->resize(implWidth, implHeight);
|
_impl->resize(implWidth, implHeight);
|
||||||
}
|
}
|
||||||
QSize newSize(newWidth, _height);
|
return _height;
|
||||||
if (newSize != size()) {
|
|
||||||
resize(newSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotKeyboard::maximizeSize() const {
|
bool BotKeyboard::maximizeSize() const {
|
||||||
|
|
|
@ -354,7 +354,6 @@ class BotKeyboard : public TWidget, public AbstractTooltipShower, public ClickHa
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BotKeyboard();
|
BotKeyboard();
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -373,7 +372,10 @@ public:
|
||||||
bool forceReply() const;
|
bool forceReply() const;
|
||||||
|
|
||||||
void step_selected(uint64 ms, bool timer);
|
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 maximizeSize() const;
|
||||||
bool singleUse() const;
|
bool singleUse() const;
|
||||||
|
@ -390,6 +392,9 @@ public:
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,15 @@ void LayerStackWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
void LayerStackWidget::keyPressEvent(QKeyEvent *e) {
|
void LayerStackWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
if (e->key() == Qt::Key_Escape) {
|
if (e->key() == Qt::Key_Escape) {
|
||||||
onClose();
|
onCloseCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerStackWidget::mousePressEvent(QMouseEvent *e) {
|
void LayerStackWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
|
onCloseCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerStackWidget::onCloseCurrent() {
|
||||||
if (layer()) {
|
if (layer()) {
|
||||||
onCloseLayers();
|
onCloseLayers();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -73,6 +73,7 @@ public:
|
||||||
|
|
||||||
bool contentOverlapped(const QRect &globalRect);
|
bool contentOverlapped(const QRect &globalRect);
|
||||||
|
|
||||||
|
void onCloseCurrent();
|
||||||
void onCloseLayers();
|
void onCloseLayers();
|
||||||
void onClose();
|
void onClose();
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ int CoverWidget::countPhotoLeft(int newWidth) const {
|
||||||
return qMin(result, st::profilePhotoLeftMax);
|
return qMin(result, st::profilePhotoLeftMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverWidget::resizeToWidth(int newWidth) {
|
int CoverWidget::resizeGetHeight(int newWidth) {
|
||||||
int newHeight = 0;
|
int newHeight = 0;
|
||||||
|
|
||||||
newHeight += st::profileMarginTop;
|
newHeight += st::profileMarginTop;
|
||||||
|
@ -137,9 +137,8 @@ void CoverWidget::resizeToWidth(int newWidth) {
|
||||||
|
|
||||||
newHeight += st::profileBlocksTop;
|
newHeight += st::profileBlocksTop;
|
||||||
|
|
||||||
resizeDropArea();
|
resizeDropArea(newWidth);
|
||||||
resize(newWidth, newHeight);
|
return newHeight;
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverWidget::refreshNameGeometry(int newWidth) {
|
void CoverWidget::refreshNameGeometry(int newWidth) {
|
||||||
|
@ -210,9 +209,9 @@ void CoverWidget::paintEvent(QPaintEvent *e) {
|
||||||
paintDivider(p);
|
paintDivider(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverWidget::resizeDropArea() {
|
void CoverWidget::resizeDropArea(int newWidth) {
|
||||||
if (_dropArea) {
|
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);
|
subtitle = lang(lng_profile_drop_area_subtitle_channel);
|
||||||
}
|
}
|
||||||
_dropArea = new CoverDropArea(this, title, subtitle);
|
_dropArea = new CoverDropArea(this, title, subtitle);
|
||||||
resizeDropArea();
|
resizeDropArea(width());
|
||||||
}
|
}
|
||||||
_dropArea->showAnimated();
|
_dropArea->showAnimated();
|
||||||
e->setDropAction(Qt::CopyAction);
|
e->setDropAction(Qt::CopyAction);
|
||||||
|
|
|
@ -46,9 +46,6 @@ class CoverWidget final : public TWidget, public Notify::Observer {
|
||||||
public:
|
public:
|
||||||
CoverWidget(QWidget *parent, PeerData *peer);
|
CoverWidget(QWidget *parent, PeerData *peer);
|
||||||
|
|
||||||
// Count new height for width=newWidth and resize to it.
|
|
||||||
void resizeToWidth(int newWidth);
|
|
||||||
|
|
||||||
void showFinished();
|
void showFinished();
|
||||||
|
|
||||||
// Profile fixed top bar should use this flag to decide
|
// Profile fixed top bar should use this flag to decide
|
||||||
|
@ -78,6 +75,8 @@ protected:
|
||||||
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
||||||
void dropEvent(QDropEvent *e) override;
|
void dropEvent(QDropEvent *e) override;
|
||||||
|
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Observed notifications.
|
// Observed notifications.
|
||||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||||
|
@ -105,7 +104,7 @@ private:
|
||||||
|
|
||||||
bool canEditPhoto() const;
|
bool canEditPhoto() const;
|
||||||
void showSetPhotoBox(const QImage &img);
|
void showSetPhotoBox(const QImage &img);
|
||||||
void resizeDropArea();
|
void resizeDropArea(int newWidth);
|
||||||
void dropAreaHidden(CoverDropArea *dropArea);
|
void dropAreaHidden(CoverDropArea *dropArea);
|
||||||
bool mimeDataHasImage(const QMimeData *mimeData) const;
|
bool mimeDataHasImage(const QMimeData *mimeData) const;
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,10 @@ public:
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resizeToWidth(int newWidth) {
|
|
||||||
resize(newWidth, st::profileTopBarHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
int resizeGetHeight(int newWidth) override {
|
||||||
|
return st::profileTopBarHeight;
|
||||||
|
}
|
||||||
void paintEvent(QPaintEvent *e) override {
|
void paintEvent(QPaintEvent *e) override {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
@ -224,7 +223,7 @@ void FixedBar::onLeaveGroupSure() {
|
||||||
App::main()->deleteAndExit(_peerChat);
|
App::main()->deleteAndExit(_peerChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedBar::resizeToWidth(int newWidth) {
|
int FixedBar::resizeGetHeight(int newWidth) {
|
||||||
int newHeight = 0;
|
int newHeight = 0;
|
||||||
|
|
||||||
int buttonLeft = newWidth;
|
int buttonLeft = newWidth;
|
||||||
|
@ -238,7 +237,7 @@ void FixedBar::resizeToWidth(int newWidth) {
|
||||||
_backButton->moveToLeft(0, 0);
|
_backButton->moveToLeft(0, 0);
|
||||||
newHeight += _backButton->height();
|
newHeight += _backButton->height();
|
||||||
|
|
||||||
resize(newWidth, newHeight);
|
return newHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedBar::setAnimatingMode(bool enabled) {
|
void FixedBar::setAnimatingMode(bool enabled) {
|
||||||
|
|
|
@ -40,8 +40,6 @@ class FixedBar final : public TWidget, public Notify::Observer {
|
||||||
public:
|
public:
|
||||||
FixedBar(QWidget *parent, PeerData *peer);
|
FixedBar(QWidget *parent, PeerData *peer);
|
||||||
|
|
||||||
void resizeToWidth(int newWidth);
|
|
||||||
|
|
||||||
// When animating mode is enabled the content is hidden and the
|
// When animating mode is enabled the content is hidden and the
|
||||||
// whole fixed bar acts like a back button.
|
// whole fixed bar acts like a back button.
|
||||||
void setAnimatingMode(bool enabled);
|
void setAnimatingMode(bool enabled);
|
||||||
|
@ -51,6 +49,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onBack();
|
void onBack();
|
||||||
|
|
|
@ -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) {
|
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
_visibleTop = visibleTop;
|
_visibleTop = visibleTop;
|
||||||
_visibleBottom = visibleBottom;
|
_visibleBottom = visibleBottom;
|
||||||
|
@ -225,7 +219,10 @@ int InnerWidget::resizeGetHeight(int newWidth) {
|
||||||
refreshBlocksPositions();
|
refreshBlocksPositions();
|
||||||
|
|
||||||
update();
|
update();
|
||||||
return countHeight();
|
auto naturalHeight = countHeight();
|
||||||
|
|
||||||
|
_addedHeight = qMax(_minHeight - naturalHeight, 0);
|
||||||
|
return naturalHeight + _addedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::countHeight() const {
|
int InnerWidget::countHeight() const {
|
||||||
|
|
|
@ -35,8 +35,10 @@ public:
|
||||||
return _peer;
|
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.
|
// Updates the area that is visible inside the scroll container.
|
||||||
void setVisibleTopBottom(int visibleTop, int visibleBottom);
|
void setVisibleTopBottom(int visibleTop, int visibleBottom);
|
||||||
|
@ -58,12 +60,12 @@ protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
|
// Resizes content and counts natural widget height for the desired width.
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createBlocks();
|
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.
|
// Counts the natural widget height after resizing of child widgets.
|
||||||
int countHeight() const;
|
int countHeight() const;
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ private:
|
||||||
// Height that we added to the natural height so that it is allowed
|
// Height that we added to the natural height so that it is allowed
|
||||||
// to scroll down to the desired position.
|
// to scroll down to the desired position.
|
||||||
int _addedHeight = 0;
|
int _addedHeight = 0;
|
||||||
|
int _minHeight = 0;
|
||||||
int _visibleTop = 0;
|
int _visibleTop = 0;
|
||||||
int _visibleBottom = 0;
|
int _visibleBottom = 0;
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,9 @@ settingsSecondaryButton: RoundButton(settingsPrimaryButton) {
|
||||||
settingsBlocksTop: 7px;
|
settingsBlocksTop: 7px;
|
||||||
settingsBlocksBottom: 20px;
|
settingsBlocksBottom: 20px;
|
||||||
settingsBlockMarginTop: 14px;
|
settingsBlockMarginTop: 14px;
|
||||||
settingsBlockMarginBottom: 7px;
|
settingsBlockMarginRight: 10px;
|
||||||
settingsBlockTitleHeight: 24px;
|
settingsBlockMarginBottom: 16px;
|
||||||
|
settingsBlockTitleHeight: 31px;
|
||||||
settingsBlockTitleFont: font(14px semibold);
|
settingsBlockTitleFont: font(14px semibold);
|
||||||
settingsBlockTitleFg: #333333;
|
settingsBlockTitleFg: #333333;
|
||||||
settingsBlockTitleTop: 0px;
|
settingsBlockTitleTop: 0px;
|
||||||
|
@ -99,5 +100,20 @@ settingsBlockOneLineTextPart: flatLabel(labelDefFlat) {
|
||||||
margin: margins(5px, 5px, 5px, 5px);
|
margin: margins(5px, 5px, 5px, 5px);
|
||||||
maxHeight: 20px;
|
maxHeight: 20px;
|
||||||
}
|
}
|
||||||
settingsBlockOneLineSkip: 9px;
|
settingsSubSkip: 4px;
|
||||||
settingsBlockOneLineWidthMax: 240px;
|
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;
|
||||||
|
|
|
@ -23,21 +23,76 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include "boxes/connectionbox.h"
|
||||||
|
#include "boxes/confirmbox.h"
|
||||||
|
#include "boxes/aboutbox.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
AdvancedWidget::AdvancedWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_advanced)) {
|
AdvancedWidget::AdvancedWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_advanced_settings)) {
|
||||||
refreshControls();
|
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) {
|
void AdvancedWidget::onManageLocalStorage() {
|
||||||
int newHeight = contentTop();
|
|
||||||
|
|
||||||
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<MTPUser>(1, support.c_help_support().vuser))) {
|
||||||
|
Ui::showPeerHistory(user, ShowAtUnreadMsgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvancedWidget::onTelegramFAQ() {
|
||||||
|
QDesktopServices::openUrl(telegramFaqLink());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvancedWidget::onLogOut() {
|
||||||
|
App::wnd()->onLogout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -21,19 +21,39 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "settings/settings_block_widget.h"
|
#include "settings/settings_block_widget.h"
|
||||||
|
#include "settings/settings_chat_settings_widget.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class AdvancedWidget : public BlockWidget {
|
class AdvancedWidget : public BlockWidget, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AdvancedWidget(QWidget *parent, UserData *self);
|
AdvancedWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
private slots:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
void onManageLocalStorage();
|
||||||
int resizeGetHeight(int newWidth) override;
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
|
void onConnectionType();
|
||||||
|
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
|
void onAskQuestion();
|
||||||
|
void onAskQuestionSure();
|
||||||
|
void onTelegramFAQ();
|
||||||
|
void onLogOut();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
void createControls();
|
||||||
|
void supportGot(const MTPhelp_Support &support);
|
||||||
|
|
||||||
|
ChildWidget<LinkButton> _manageLocalStorage = { nullptr };
|
||||||
|
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
|
ChildWidget<LabeledLink> _connectionType = { nullptr };
|
||||||
|
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||||
|
ChildWidget<LinkButton> _askQuestion = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _telegramFAQ = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _logOut = { nullptr };
|
||||||
|
|
||||||
|
mtpRequestId _supportGetRequest = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "settings/settings_block_widget.h"
|
#include "settings/settings_block_widget.h"
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
|
#include "ui/flatcheckbox.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
|
@ -38,6 +39,23 @@ int BlockWidget::contentTop() const {
|
||||||
return emptyTitle() ? 0 : (st::settingsBlockMarginTop + st::settingsBlockTitleHeight);
|
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) {
|
void BlockWidget::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
@ -54,4 +72,31 @@ void BlockWidget::paintTitle(Painter &p) {
|
||||||
p.drawTextLeft(contentLeft(), titleTop, width(), _title);
|
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<Checkbox> &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<Radiobutton> &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<LinkButton> &child, style::margins &margin, const QString &text, const char *slot) {
|
||||||
|
child = new LinkButton(this, text);
|
||||||
|
connect(child, SIGNAL(changed()), this, slot);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -22,6 +22,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/observer.h"
|
#include "core/observer.h"
|
||||||
|
|
||||||
|
class Checkbox;
|
||||||
|
class Radiobutton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
template <typename Widget>
|
||||||
|
class WidgetSlideWrap;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class BlockWidget : public ScrolledWidget, public Notify::Observer, public base::Subscriber {
|
class BlockWidget : public ScrolledWidget, public Notify::Observer, public base::Subscriber {
|
||||||
|
@ -44,7 +52,7 @@ protected:
|
||||||
int contentTop() const;
|
int contentTop() const;
|
||||||
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
// Resizes content and counts natural widget height for the desired width.
|
||||||
int resizeGetHeight(int newWidth) override = 0;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
void contentSizeUpdated() {
|
void contentSizeUpdated() {
|
||||||
resizeToWidth(width());
|
resizeToWidth(width());
|
||||||
|
@ -59,9 +67,62 @@ protected:
|
||||||
return _title.isEmpty();
|
return _title.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Widget, typename ...Args>
|
||||||
|
Widget *addChildRow(ChildWidget<Widget> &child, style::margins margin, Args&&... args) {
|
||||||
|
createChildRow(child, margin, std_::forward<Args>(args)...);
|
||||||
|
addCreatedRow(child, margin);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename Widget, typename ...Args>
|
||||||
|
void createChildRow(ChildWidget<Ui::WidgetSlideWrap<Widget>> &child, style::margins &margin, const style::margins &padding, Args&&... args) {
|
||||||
|
ChildWidget<Widget> plainChild = { nullptr };
|
||||||
|
createChildRow(plainChild, margin, std_::forward<Args>(args)...);
|
||||||
|
child = new Ui::WidgetSlideWrap<Widget>(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<Checkbox> &child, style::margins &margin, const QString &text, const char *slot, bool checked);
|
||||||
|
void createChildRow(ChildWidget<Radiobutton> &child, style::margins &margin, const QString &group, int value, const QString &text, const char *slot, bool checked);
|
||||||
|
void createChildRow(ChildWidget<LinkButton> &child, style::margins &margin, const QString &text, const char *slot);
|
||||||
|
|
||||||
|
void addCreatedRow(TWidget *child, const style::margins &margin);
|
||||||
|
void rowHeightUpdated();
|
||||||
|
|
||||||
|
template <typename Widget>
|
||||||
|
struct IsWidgetSlideWrap {
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
template <typename Widget>
|
||||||
|
struct IsWidgetSlideWrap<Ui::WidgetSlideWrap<Widget>> {
|
||||||
|
static constexpr bool value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Widget>
|
||||||
|
using NotImplementedYet = std_::enable_if_t<
|
||||||
|
!IsWidgetSlideWrap<Widget>::value &&
|
||||||
|
!std_::is_same<Widget, Checkbox>::value &&
|
||||||
|
!std_::is_same<Widget, Radiobutton>::value &&
|
||||||
|
!std_::is_same<Widget, LinkButton>::value>;
|
||||||
|
|
||||||
|
template <typename Widget, typename... Args, typename = NotImplementedYet<Widget>>
|
||||||
|
void createChildRow(ChildWidget<Widget> &child, style::margins &margin, Args&&... args) {
|
||||||
|
child = new Widget(this, std_::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
void paintTitle(Painter &p);
|
void paintTitle(Painter &p);
|
||||||
|
|
||||||
|
struct ChildRow {
|
||||||
|
TWidget *child;
|
||||||
|
style::margins margin;
|
||||||
|
};
|
||||||
|
QVector<ChildRow> _rows;
|
||||||
|
|
||||||
int _contentLeft = 0;
|
int _contentLeft = 0;
|
||||||
UserData *_self;
|
UserData *_self;
|
||||||
QString _title;
|
QString _title;
|
||||||
|
|
|
@ -23,21 +23,122 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.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 {
|
namespace Settings {
|
||||||
|
|
||||||
ChatSettingsWidget::ChatSettingsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_chat_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) {
|
LabeledLink::LabeledLink(QWidget *parent, const QString &label, const QString &text) : TWidget(parent)
|
||||||
int newHeight = contentTop();
|
, _label(this, label, FlatLabel::InitType::Simple)
|
||||||
|
, _link(this, text) {
|
||||||
|
}
|
||||||
|
|
||||||
newHeight += st::settingsBlockMarginBottom;
|
void LabeledLink::setLink(const QString &text) {
|
||||||
return newHeight;
|
_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
|
} // namespace Settings
|
||||||
|
|
|
@ -22,18 +22,58 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "settings/settings_block_widget.h"
|
#include "settings/settings_block_widget.h"
|
||||||
|
|
||||||
|
class FlatLabel;
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class ChatSettingsWidget : public BlockWidget {
|
class LabeledLink : public TWidget {
|
||||||
public:
|
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:
|
protected:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
ChildWidget<FlatLabel> _label;
|
||||||
|
ChildWidget<LinkButton> _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<Checkbox> _replaceEmoji = { nullptr };
|
||||||
|
ChildWidget<Ui::WidgetSlideWrap<LinkButton>> _viewList = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _dontAskDownloadPath = { nullptr };
|
||||||
|
ChildWidget<Ui::WidgetSlideWrap<LabeledLink>> _downloadPath = { nullptr };
|
||||||
|
ChildWidget<Radiobutton> _sendByEnter = { nullptr };
|
||||||
|
ChildWidget<Radiobutton> _sendByCtrlEnter = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _automaticMediaDownloadSettings = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _manageStickerSets = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ FixedBar::FixedBar(QWidget *parent) : TWidget(parent)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedBar::resizeToWidth(int newWidth) {
|
int FixedBar::resizeGetHeight(int newWidth) {
|
||||||
resize(newWidth, st::settingsFixedBarHeight);
|
return st::settingsFixedBarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedBar::resizeEvent(QResizeEvent *e) {
|
void FixedBar::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
|
@ -30,12 +30,12 @@ class FixedBar : public TWidget {
|
||||||
public:
|
public:
|
||||||
FixedBar(QWidget *parent);
|
FixedBar(QWidget *parent);
|
||||||
|
|
||||||
void resizeToWidth(int newWidth);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildWidget<Ui::IconButton> _close;
|
ChildWidget<Ui::IconButton> _close;
|
||||||
|
|
||||||
|
|
|
@ -23,21 +23,180 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.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 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();
|
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) {
|
void GeneralWidget::refreshControls() {
|
||||||
int newHeight = contentTop();
|
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;
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
return newHeight;
|
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
|
} // namespace Settings
|
||||||
|
|
|
@ -21,19 +21,62 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "settings/settings_block_widget.h"
|
#include "settings/settings_block_widget.h"
|
||||||
|
#include "ui/filedialog.h"
|
||||||
|
|
||||||
|
class Checkbox;
|
||||||
|
class LinkButton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
template <typename Widget>
|
||||||
|
class WidgetSlideWrap;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class GeneralWidget : public BlockWidget {
|
class GeneralWidget : public BlockWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GeneralWidget(QWidget *parent, UserData *self);
|
GeneralWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
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:
|
private:
|
||||||
void refreshControls();
|
void refreshControls();
|
||||||
|
void updateWorkmode();
|
||||||
|
void chooseCustomLang();
|
||||||
|
void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update);
|
||||||
|
|
||||||
|
ChildWidget<LinkButton> _changeLanguage;
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
ChildWidget<Checkbox> _updateAutomatically = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _checkForUpdates = { nullptr };
|
||||||
|
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
ChildWidget<Checkbox> _enableTrayIcon = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _enableTaskbarIcon = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _autoStart = { nullptr };
|
||||||
|
ChildWidget<Ui::WidgetSlideWrap<Checkbox>> _startMinimized = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _addInSendTo = { nullptr };
|
||||||
|
|
||||||
|
FileDialog::QueryId _chooseLangFileQueryId = 0;
|
||||||
|
QString _testLanguage;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,21 +23,182 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.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 {
|
namespace Settings {
|
||||||
|
|
||||||
|
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||||
|
|
||||||
InfoWidget::InfoWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_info)) {
|
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();
|
refreshControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoWidget::refreshControls() {
|
void InfoWidget::refreshControls() {
|
||||||
|
refreshMobileNumber();
|
||||||
|
refreshUsername();
|
||||||
|
refreshLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
int InfoWidget::resizeGetHeight(int newWidth) {
|
void InfoWidget::refreshMobileNumber() {
|
||||||
int newHeight = contentTop();
|
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;
|
void InfoWidget::refreshUsername() {
|
||||||
return newHeight;
|
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<LabeledWrap> &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<FlatLabel> &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
|
} // namespace Settings
|
||||||
|
|
|
@ -34,30 +34,51 @@ class InfoWidget : public BlockWidget {
|
||||||
public:
|
public:
|
||||||
InfoWidget(QWidget *parent, UserData *self);
|
InfoWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Observed notifications.
|
// Observed notifications.
|
||||||
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
void notifyPeerUpdated(const Notify::PeerUpdate &update);
|
||||||
|
|
||||||
|
bool usernameClickHandlerHook(const ClickHandlerPtr &handler, Qt::MouseButton button);
|
||||||
|
|
||||||
|
void createControls();
|
||||||
void refreshControls();
|
void refreshControls();
|
||||||
void refreshMobileNumber();
|
void refreshMobileNumber();
|
||||||
void refreshUsername();
|
void refreshUsername();
|
||||||
void refreshLink();
|
void refreshLink();
|
||||||
|
|
||||||
// labelWidget may be nullptr.
|
class LabeledWidget : public TWidget {
|
||||||
void setLabeledText(ChildWidget<FlatLabel> *labelWidget, const QString &label,
|
public:
|
||||||
ChildWidget<FlatLabel> *textWidget, const TextWithEntities &textWithEntities, const QString ©Text);
|
LabeledWidget(QWidget *parent);
|
||||||
|
|
||||||
ChildWidget<FlatLabel> _mobileNumberLabel = { nullptr };
|
void setLabeledText(const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text);
|
||||||
ChildWidget<FlatLabel> _mobileNumber = { nullptr };
|
|
||||||
ChildWidget<FlatLabel> _usernameLabel = { nullptr };
|
FlatLabel *textLabel() {
|
||||||
ChildWidget<FlatLabel> _username = { nullptr };
|
return _text;
|
||||||
ChildWidget<FlatLabel> _linkLabel = { nullptr };
|
}
|
||||||
ChildWidget<FlatLabel> _link = { nullptr };
|
FlatLabel *shortTextLabel() {
|
||||||
ChildWidget<FlatLabel> _linkShort = { nullptr };
|
return _shortText;
|
||||||
|
}
|
||||||
|
|
||||||
|
int naturalWidth() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setLabelText(ChildWidget<FlatLabel> &text, const TextWithEntities &textWithEntities, const QString ©Text);
|
||||||
|
|
||||||
|
ChildWidget<FlatLabel> _label = { nullptr };
|
||||||
|
ChildWidget<FlatLabel> _text = { nullptr };
|
||||||
|
ChildWidget<FlatLabel> _shortText = { nullptr };
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using LabeledWrap = Ui::WidgetSlideWrap<LabeledWidget>;
|
||||||
|
void setLabeledText(ChildWidget<LabeledWrap> &row, const QString &label, const TextWithEntities &textWithEntities, const TextWithEntities &shortTextWithEntities, const QString ©Text);
|
||||||
|
|
||||||
|
ChildWidget<LabeledWrap> _mobileNumber = { nullptr };
|
||||||
|
ChildWidget<LabeledWrap> _username = { nullptr };
|
||||||
|
ChildWidget<LabeledWrap> _link = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,9 @@ void InnerWidget::refreshBlocks() {
|
||||||
_blocks.push_back(new Settings::PrivacyWidget(this, _self));
|
_blocks.push_back(new Settings::PrivacyWidget(this, _self));
|
||||||
}
|
}
|
||||||
_blocks.push_back(new Settings::AdvancedWidget(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() {
|
void InnerWidget::showFinished() {
|
||||||
|
@ -68,32 +71,40 @@ void InnerWidget::showFinished() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::resizeToWidth(int newWidth, int contentLeft) {
|
int InnerWidget::resizeGetHeight(int newWidth) {
|
||||||
int newHeight = resizeGetHeight(newWidth, contentLeft);
|
if (_cover) {
|
||||||
resize(newWidth, newHeight);
|
_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 InnerWidget::refreshBlocksPositions() {
|
||||||
int result = 0;
|
int result = (_cover ? _cover->height() : 0) + st::settingsBlocksTop;
|
||||||
if (_cover) {
|
|
||||||
_cover->setContentLeft(contentLeft);
|
|
||||||
_cover->resizeToWidth(newWidth);
|
|
||||||
result += _cover->height();
|
|
||||||
}
|
|
||||||
result += st::settingsBlocksTop;
|
|
||||||
for_const (auto block, _blocks) {
|
for_const (auto block, _blocks) {
|
||||||
if (block->isHidden()) {
|
if (block->isHidden()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->moveToLeft(0, result);
|
block->moveToLeft(0, result);
|
||||||
block->setContentLeft(contentLeft);
|
|
||||||
block->resizeToWidth(newWidth);
|
|
||||||
result += block->height();
|
result += block->height();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::onBlockHeightUpdated() {
|
||||||
|
int newHeight = refreshBlocksPositions();
|
||||||
|
if (newHeight != height()) {
|
||||||
|
resize(width(), newHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
_visibleTop = visibleTop;
|
_visibleTop = visibleTop;
|
||||||
_visibleBottom = visibleBottom;
|
_visibleBottom = visibleBottom;
|
||||||
|
|
|
@ -26,28 +26,42 @@ class CoverWidget;
|
||||||
class BlockWidget;
|
class BlockWidget;
|
||||||
|
|
||||||
class InnerWidget : public TWidget {
|
class InnerWidget : public TWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InnerWidget(QWidget *parent);
|
InnerWidget(QWidget *parent);
|
||||||
|
|
||||||
// Count new height for width=newWidth and resize to it.
|
// 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.
|
// Updates the area that is visible inside the scroll container.
|
||||||
void setVisibleTopBottom(int visibleTop, int visibleBottom);
|
void setVisibleTopBottom(int visibleTop, int visibleBottom);
|
||||||
|
|
||||||
void showFinished();
|
void showFinished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onBlockHeightUpdated();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Resizes content and counts natural widget height for the desired width.
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshBlocks();
|
void refreshBlocks();
|
||||||
|
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
// Returns the new height value.
|
||||||
int resizeGetHeight(int newWidth, int contentLeft);
|
int refreshBlocksPositions();
|
||||||
|
|
||||||
ChildWidget<CoverWidget> _cover = { nullptr };
|
ChildWidget<CoverWidget> _cover = { nullptr };
|
||||||
QList<BlockWidget*> _blocks;
|
QList<BlockWidget*> _blocks;
|
||||||
|
|
||||||
UserData *_self = nullptr;
|
UserData *_self = nullptr;
|
||||||
|
|
||||||
|
int _contentLeft = 0;
|
||||||
|
|
||||||
int _visibleTop = 0;
|
int _visibleTop = 0;
|
||||||
int _visibleBottom = 0;
|
int _visibleBottom = 0;
|
||||||
|
|
||||||
|
|
|
@ -23,21 +23,105 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include "localstorage.h"
|
||||||
|
#include "ui/widgets/widget_slide_wrap.h"
|
||||||
|
#include "ui/flatcheckbox.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_notify)) {
|
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) {
|
void NotificationsWidget::onDesktopNotifications() {
|
||||||
int newHeight = contentTop();
|
cSetDesktopNotify(_desktopNotifications->checked());
|
||||||
|
Local::writeUserSettings();
|
||||||
|
if (App::wnd()) App::wnd()->updateTrayMenu();
|
||||||
|
|
||||||
newHeight += st::settingsBlockMarginBottom;
|
if (_desktopNotifications->checked()) {
|
||||||
return newHeight;
|
_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
|
} // namespace Settings
|
||||||
|
|
|
@ -25,15 +25,30 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class NotificationsWidget : public BlockWidget {
|
class NotificationsWidget : public BlockWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotificationsWidget(QWidget *parent, UserData *self);
|
NotificationsWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
private slots:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
void onDesktopNotifications();
|
||||||
int resizeGetHeight(int newWidth) override;
|
void onShowSenderName();
|
||||||
|
void onShowMessagePreview();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
void onWindowsNative();
|
||||||
|
#endif // Q_OS_WIN
|
||||||
|
void onPlaySound();
|
||||||
|
void onIncludeMuted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
void createControls();
|
||||||
|
|
||||||
|
ChildWidget<Checkbox> _desktopNotifications = { nullptr };
|
||||||
|
ChildWidget<Ui::WidgetSlideWrap<Checkbox>> _showSenderName = { nullptr };
|
||||||
|
ChildWidget<Ui::WidgetSlideWrap<Checkbox>> _showMessagePreview = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _windowsNative = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _playSound = { nullptr };
|
||||||
|
ChildWidget<Checkbox> _includeMuted = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,25 @@ PrivacyWidget::PrivacyWidget(QWidget *parent, UserData *self) : BlockWidget(pare
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrivacyWidget::refreshControls() {
|
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) {
|
void PrivacyWidget::onEditPasscode() {
|
||||||
int newHeight = contentTop();
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivacyWidget::onEditPassword() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivacyWidget::onShowSessions() {
|
||||||
|
|
||||||
newHeight += st::settingsBlockMarginBottom;
|
|
||||||
return newHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -25,16 +25,23 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
class PrivacyWidget : public BlockWidget {
|
class PrivacyWidget : public BlockWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrivacyWidget(QWidget *parent, UserData *self);
|
PrivacyWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
private slots:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
void onEditPasscode();
|
||||||
int resizeGetHeight(int newWidth) override;
|
void onEditPassword();
|
||||||
|
void onShowSessions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
void refreshControls();
|
||||||
|
|
||||||
|
ChildWidget<LinkButton> _editPasscode = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _editPassword = { nullptr };
|
||||||
|
ChildWidget<LinkButton> _showAllSessions = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -23,21 +23,244 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include "localstorage.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "boxes/confirmbox.h"
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
namespace Settings {
|
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)) {
|
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) {
|
void ScaleWidget::onAutoChosen() {
|
||||||
int newHeight = contentTop();
|
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;
|
void ScaleWidget::setScale(DBIScale newScale) {
|
||||||
return newHeight;
|
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
|
} // namespace Settings
|
||||||
|
|
|
@ -22,18 +22,74 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "settings/settings_block_widget.h"
|
#include "settings/settings_block_widget.h"
|
||||||
|
|
||||||
|
class Checkbox;
|
||||||
|
|
||||||
namespace Settings {
|
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<Section> _sections;
|
||||||
|
int _activeIndex = 0;
|
||||||
|
|
||||||
|
bool _pressed = false;
|
||||||
|
int _selected = 0;
|
||||||
|
anim::ivalue a_left = { 0 };
|
||||||
|
Animation _a_left;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class ScaleWidget : public BlockWidget {
|
class ScaleWidget : public BlockWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScaleWidget(QWidget *parent, UserData *self);
|
ScaleWidget(QWidget *parent, UserData *self);
|
||||||
|
|
||||||
protected:
|
private slots:
|
||||||
// Resizes content and counts natural widget height for the desired width.
|
void onAutoChosen();
|
||||||
int resizeGetHeight(int newWidth) override;
|
void onSectionActivated();
|
||||||
|
void onRestartNow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshControls();
|
void createControls();
|
||||||
|
void setScale(DBIScale newScale);
|
||||||
|
|
||||||
|
ChildWidget<Checkbox> _auto = { nullptr };
|
||||||
|
ChildWidget<Slider> _scale = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
|
||||||
// general
|
// general
|
||||||
, _changeLanguage(this, lang(lng_settings_change_lang))
|
, _changeLanguage(this, lang(lng_settings_change_lang))
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
, _autoUpdate(this, lang(lng_settings_auto_update), cAutoUpdate())
|
, _autoUpdate(this, QString(), cAutoUpdate())
|
||||||
, _checkNow(this, lang(lng_settings_check_now))
|
, _checkNow(this, lang(lng_settings_check_now))
|
||||||
, _restartNow(this, lang(lng_settings_update_now))
|
, _restartNow(this, lang(lng_settings_update_now))
|
||||||
#endif
|
#endif
|
||||||
|
@ -672,7 +672,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
// advanced
|
// advanced
|
||||||
p.setFont(st::setHeaderFont->f);
|
p.setFont(st::setHeaderFont->f);
|
||||||
p.setPen(st::setHeaderColor->p);
|
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;
|
top += st::setHeaderSkip;
|
||||||
|
|
||||||
p.setFont(st::linkFont->f);
|
p.setFont(st::linkFont->f);
|
||||||
|
|
|
@ -42,13 +42,13 @@ void LeftOutlineButton::setText(const QString &text) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeftOutlineButton::resizeToWidth(int newWidth) {
|
int LeftOutlineButton::resizeGetHeight(int newWidth) {
|
||||||
int availableWidth = qMax(newWidth - _st.padding.left() - _st.padding.right(), 1);
|
int availableWidth = qMax(newWidth - _st.padding.left() - _st.padding.right(), 1);
|
||||||
if ((availableWidth < _fullTextWidth) || (_textWidth < availableWidth)) {
|
if ((availableWidth < _fullTextWidth) || (_textWidth < availableWidth)) {
|
||||||
_text = _st.font->elided(_fullText, availableWidth);
|
_text = _st.font->elided(_fullText, availableWidth);
|
||||||
_textWidth = _st.font->width(_text);
|
_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) {
|
void LeftOutlineButton::paintEvent(QPaintEvent *e) {
|
||||||
|
|
|
@ -28,7 +28,6 @@ class LeftOutlineButton : public Button {
|
||||||
public:
|
public:
|
||||||
LeftOutlineButton(QWidget *parent, const QString &text, const style::OutlineButton &st = st::defaultLeftOutlineButton);
|
LeftOutlineButton(QWidget *parent, const QString &text, const style::OutlineButton &st = st::defaultLeftOutlineButton);
|
||||||
|
|
||||||
void resizeToWidth(int newWidth);
|
|
||||||
void setText(const QString &text);
|
void setText(const QString &text);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -36,6 +35,8 @@ protected:
|
||||||
|
|
||||||
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
||||||
|
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _text, _fullText;
|
QString _text, _fullText;
|
||||||
int _textWidth, _fullTextWidth;
|
int _textWidth, _fullTextWidth;
|
||||||
|
|
|
@ -127,6 +127,10 @@ LinkButton::LinkButton(QWidget *parent, const QString &text, const style::linkBu
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LinkButton::naturalWidth() const {
|
||||||
|
return _st.font->width(_text);
|
||||||
|
}
|
||||||
|
|
||||||
void LinkButton::paintEvent(QPaintEvent *e) {
|
void LinkButton::paintEvent(QPaintEvent *e) {
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.setFont(((_state & StateOver) ? _st.overFont : _st.font)->f);
|
p.setFont(((_state & StateOver) ? _st.overFont : _st.font)->f);
|
||||||
|
|
|
@ -66,23 +66,24 @@ class LinkButton : public Button {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LinkButton(QWidget *parent, const QString &text, const style::linkButton &st = st::btnDefLink);
|
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);
|
void setText(const QString &text);
|
||||||
|
|
||||||
~LinkButton();
|
~LinkButton();
|
||||||
|
|
||||||
public slots:
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
void onStateChange(int oldState, ButtonStateChangeSource source);
|
void onStateChange(int oldState, ButtonStateChangeSource source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString _text;
|
QString _text;
|
||||||
style::linkButton _st;
|
style::linkButton _st;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IconedButton : public Button {
|
class IconedButton : public Button {
|
||||||
|
|
|
@ -310,6 +310,10 @@ void Checkbox::step_checked(float64 ms, bool timer) {
|
||||||
if (timer) update(_checkRect);
|
if (timer) update(_checkRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Checkbox::naturalWidth() const {
|
||||||
|
return _st.textPosition.x() + _st.font->width(_fullText);
|
||||||
|
}
|
||||||
|
|
||||||
void Checkbox::paintEvent(QPaintEvent *e) {
|
void Checkbox::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,10 @@ public:
|
||||||
|
|
||||||
void finishAnimations();
|
void finishAnimations();
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e);
|
int naturalWidth() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onClicked();
|
void onClicked();
|
||||||
|
|
|
@ -112,11 +112,13 @@ void FlatLabel::setBreakEverywhere(bool breakEverywhere) {
|
||||||
_breakEverywhere = breakEverywhere;
|
_breakEverywhere = breakEverywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatLabel::resizeToWidth(int32 width) {
|
int FlatLabel::resizeGetHeight(int newWidth) {
|
||||||
|
_allowedWidth = newWidth;
|
||||||
textstyleSet(&_tst);
|
textstyleSet(&_tst);
|
||||||
_allowedWidth = width;
|
int textWidth = countTextWidth();
|
||||||
refreshSize();
|
int textHeight = countTextHeight(textWidth);
|
||||||
textstyleRestore();
|
textstyleRestore();
|
||||||
|
return _st.margin.top() + textHeight + _st.margin.bottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FlatLabel::naturalWidth() const {
|
int FlatLabel::naturalWidth() const {
|
||||||
|
|
|
@ -43,8 +43,7 @@ public:
|
||||||
void setExpandLinksMode(ExpandLinksMode mode);
|
void setExpandLinksMode(ExpandLinksMode mode);
|
||||||
void setBreakEverywhere(bool breakEverywhere);
|
void setBreakEverywhere(bool breakEverywhere);
|
||||||
|
|
||||||
void resizeToWidth(int32 width);
|
int naturalWidth() const override;
|
||||||
int naturalWidth() const;
|
|
||||||
|
|
||||||
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
|
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
|
||||||
|
|
||||||
|
@ -70,6 +69,8 @@ protected:
|
||||||
bool event(QEvent *e) override; // calls touchEvent when necessary
|
bool event(QEvent *e) override; // calls touchEvent when necessary
|
||||||
void touchEvent(QTouchEvent *e);
|
void touchEvent(QTouchEvent *e);
|
||||||
|
|
||||||
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onCopySelectedText();
|
void onCopySelectedText();
|
||||||
void onCopyContextText();
|
void onCopyContextText();
|
||||||
|
|
|
@ -276,21 +276,10 @@ public:
|
||||||
ScrolledWidget(QWidget *parent = nullptr) : TWidget(parent) {
|
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.
|
// Updates the area that is visible inside the scroll container.
|
||||||
virtual void setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
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:
|
signals:
|
||||||
void heightUpdated();
|
void heightUpdated();
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,19 @@ public:
|
||||||
return QPointer<const TWidget>(this);
|
return QPointer<const TWidget>(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:
|
protected:
|
||||||
|
@ -217,6 +229,11 @@ protected:
|
||||||
return QWidget::leaveEvent(e);
|
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);
|
void myEnsureResized(QWidget *target);
|
||||||
|
|
164
Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h
Normal file
164
Telegram/SourceFiles/ui/widgets/widget_slide_wrap.h
Normal file
|
@ -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 <typename Widget>
|
||||||
|
class WidgetSlideWrap : public TWidget {
|
||||||
|
public:
|
||||||
|
WidgetSlideWrap(QWidget *parent, Widget *entity
|
||||||
|
, style::margins entityPadding
|
||||||
|
, base::lambda_unique<void()> &&updateCallback
|
||||||
|
, int duration = st::widgetSlideDuration) : TWidget(parent)
|
||||||
|
, _entity(entity)
|
||||||
|
, _padding(entityPadding)
|
||||||
|
, _duration(duration)
|
||||||
|
, _updateCallback(std_::move(updateCallback))
|
||||||
|
, _a_height(animation(this, &WidgetSlideWrap<Widget>::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<void()> _updateCallback;
|
||||||
|
|
||||||
|
style::size _realSize;
|
||||||
|
int _forceHeight = -1;
|
||||||
|
anim::ivalue a_height;
|
||||||
|
Animation _a_height;
|
||||||
|
bool _hiding = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -32,3 +32,5 @@ defaultLabelSimple: LabelSimple {
|
||||||
maxWidth: 0px;
|
maxWidth: 0px;
|
||||||
textFg: windowTextFg;
|
textFg: windowTextFg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
widgetSlideDuration: 200;
|
||||||
|
|
|
@ -2,5 +2,5 @@ AppVersion 10002
|
||||||
AppVersionStrMajor 0.10
|
AppVersionStrMajor 0.10
|
||||||
AppVersionStrSmall 0.10.2
|
AppVersionStrSmall 0.10.2
|
||||||
AppVersionStr 0.10.2
|
AppVersionStr 0.10.2
|
||||||
AlphaChannel 1
|
AlphaChannel 0
|
||||||
BetaVersion 0
|
BetaVersion 10002001
|
||||||
|
|
|
@ -394,6 +394,7 @@
|
||||||
'<(src_loc)/ui/toast/toast_widget.h',
|
'<(src_loc)/ui/toast/toast_widget.h',
|
||||||
'<(src_loc)/ui/widgets/label_simple.cpp',
|
'<(src_loc)/ui/widgets/label_simple.cpp',
|
||||||
'<(src_loc)/ui/widgets/label_simple.h',
|
'<(src_loc)/ui/widgets/label_simple.h',
|
||||||
|
'<(src_loc)/ui/widgets/widget_slide_wrap.h',
|
||||||
'<(src_loc)/ui/animation.cpp',
|
'<(src_loc)/ui/animation.cpp',
|
||||||
'<(src_loc)/ui/animation.h',
|
'<(src_loc)/ui/animation.h',
|
||||||
'<(src_loc)/ui/boxshadow.cpp',
|
'<(src_loc)/ui/boxshadow.cpp',
|
||||||
|
|
Loading…
Add table
Reference in a new issue