Improve new settings design.

This commit is contained in:
John Preston 2018-09-13 23:09:26 +03:00
parent ffc4cd3415
commit c2039da600
31 changed files with 463 additions and 304 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -267,7 +267,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bio_placeholder" = "Bio";
"lng_bio_about" = "You can add a few lines about yourself. Anyone who opens your profile will see this text.";
"lng_settings_section_info" = "Info";
"lng_settings_section_info" = "My info";
"lng_settings_username" = "Username:";
"lng_settings_choose_username" = "Choose username";
"lng_settings_empty_bio" = "None";
@ -353,6 +353,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_calls_title" = "Calls";
"lng_settings_peer_to_peer" = "Peer-to-Peer";
"lng_settings_peer_to_peer_about" = "Disabling peer-to-peer will relay all calls through Telegram servers to avoid revealing your IP address, but may slightly decrease audio quality.";
"lng_settings_advanced" = "Advanced";
"lng_settings_stickers_emoji" = "Stickers and emoji";
"lng_settings_themes" = "Themes";
"lng_settings_chat_other" = "Other";
"lng_backgrounds_header" = "Choose your new chat background";
"lng_theme_sure_keep" = "Keep this theme?";

View File

@ -192,7 +192,7 @@ void LocalStorageBox::Row::step_radial(TimeMs ms, bool timer) {
}
rpl::producer<> LocalStorageBox::Row::clearRequests() const {
return _clear->clicks();
return _clear->clicks() | rpl::map([] { return rpl::empty_value(); });
}
int LocalStorageBox::Row::resizeGetHeight(int newWidth) {

View File

@ -266,7 +266,7 @@ ProgressWidget::ProgressWidget(
rpl::producer<> ProgressWidget::cancelClicks() const {
return _cancel
? _cancel->clicks()
? (_cancel->clicks() | rpl::map([] { return rpl::empty_value(); }))
: (rpl::never<>() | rpl::type_erased());
}
@ -322,7 +322,10 @@ void ProgressWidget::showDone() {
if (_done->width() < desired) {
_done->setFullWidth(desired);
}
_done->clicks() | rpl::start_to_stream(_doneClicks, _done->lifetime());
_done->clicks(
) | rpl::map([] {
return rpl::empty_value();
}) | rpl::start_to_stream(_doneClicks, _done->lifetime());
setupBottomButton(_done.get());
}

View File

@ -524,7 +524,10 @@ void SettingsWidget::refreshButtons(
: nullptr;
if (start) {
start->show();
_startClicks = start->clicks();
_startClicks = start->clicks(
) | rpl::map([] {
return rpl::empty_value();
});
container->sizeValue(
) | rpl::start_with_next([=](QSize size) {
@ -539,7 +542,10 @@ void SettingsWidget::refreshButtons(
langFactory(lng_cancel),
st::defaultBoxButton);
cancel->show();
_cancelClicks = cancel->clicks();
_cancelClicks = cancel->clicks(
) | rpl::map([] {
return rpl::empty_value();
});
rpl::combine(
container->sizeValue(),

View File

@ -30,7 +30,7 @@ TopBar::TopBar(QWidget *parent, Content &&content)
updateData(std::move(content));
}
rpl::producer<> TopBar::clicks() const {
rpl::producer<Qt::MouseButton> TopBar::clicks() const {
return _button->clicks();
}

View File

@ -25,7 +25,7 @@ class TopBar : public Ui::RpWidget {
public:
TopBar(QWidget *parent, Content &&content);
rpl::producer<> clicks() const;
rpl::producer<Qt::MouseButton> clicks() const;
void updateData(Content &&content);

View File

@ -50,7 +50,7 @@ public:
rpl::producer<int> scrollHeightValue() const;
rpl::producer<int> desiredHeightValue() const override;
rpl::producer<bool> desiredShadowVisibility() const;
virtual rpl::producer<bool> desiredShadowVisibility() const;
bool hasTopBarShadow() const;
virtual void setInnerFocus();

View File

@ -99,8 +99,10 @@ void TopBar::enableBackButton() {
st::infoTopBarScale);
_back->setDuration(st::infoTopBarDuration);
_back->toggle(!selectionMode(), anim::type::instant);
_back->entity()->clicks()
| rpl::start_to_stream(_backClicks, _back->lifetime());
_back->entity()->clicks(
) | rpl::map([] {
return rpl::empty_value();
}) | rpl::start_to_stream(_backClicks, _back->lifetime());
registerToggleControlCallback(_back.data(), [=] {
return !selectionMode();
});
@ -434,7 +436,9 @@ void TopBar::createSelectionControls() {
st::infoTopBarScale));
_cancelSelection->setDuration(st::infoTopBarDuration);
_cancelSelection->entity()->clicks(
) | rpl::start_to_stream(
) | rpl::map([] {
return rpl::empty_value();
}) | rpl::start_to_stream(
_cancelSelectionClicks,
_cancelSelection->lifetime());
_selectionText = wrap(Ui::CreateChild<Ui::FadeWrap<Ui::LabelWithNumbers>>(
@ -605,7 +609,7 @@ rpl::producer<QString> TitleValue(
case Section::SettingsType::PrivacySecurity:
return lng_settings_section_privacy;
case Section::SettingsType::General:
return lng_settings_section_general;
return lng_settings_advanced;
case Section::SettingsType::Chat:
return lng_settings_section_chat_settings;
}

View File

@ -71,7 +71,7 @@ void Button::paintEvent(QPaintEvent *e) {
Painter p(this);
auto ms = getms();
auto paintOver = (isOver() || isDown());
auto paintOver = (isOver() || isDown()) && !isDisabled();
p.fillRect(e->rect(), paintOver ? _st.textBgOver : _st.textBg);
paintRipple(p, 0, 0, ms);
@ -113,10 +113,13 @@ int Button::resizeGetHeight(int newWidth) {
void Button::onStateChanged(
State was,
StateChangeSource source) {
RippleButton::onStateChanged(was, source);
if (!isDisabled() || !isDown()) {
RippleButton::onStateChanged(was, source);
}
if (_toggle) {
_toggle->setStyle(isOver() ? _st.toggleOver : _st.toggle);
}
setPointerCursor(!isDisabled());
}
void Button::setText(QString &&text) {

View File

@ -294,6 +294,8 @@ void Cover::initViewers() {
) | rpl::start_with_next(
[this] { refreshUploadPhotoOverlay(); },
lifetime());
} else if (_peer->isSelf()) {
refreshUploadPhotoOverlay();
}
VerifiedValue(
_peer
@ -304,12 +306,12 @@ void Cover::initViewers() {
void Cover::refreshUploadPhotoOverlay() {
_userpic->switchChangePhotoOverlay([&] {
if (auto chat = _peer->asChat()) {
if (const auto chat = _peer->asChat()) {
return chat->canEdit();
} else if (auto channel = _peer->asChannel()) {
} else if (const auto channel = _peer->asChannel()) {
return channel->canEditInformation();
}
return false;
return _peer->isSelf();
}());
}

View File

@ -86,6 +86,12 @@ void Widget::saveChanges(FnMut<void()> done) {
_inner->sectionSaveChanges(std::move(done));
}
rpl::producer<bool> Widget::desiredShadowVisibility() const {
return (_type == Type::Main || _type == Type::Information)
? ContentWidget::desiredShadowVisibility()
: rpl::single(true);
}
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
auto result = std::make_unique<Memento>(self(), _type);
saveState(result.get());

View File

@ -66,6 +66,8 @@ public:
rpl::producer<bool> canSaveChanges() const override;
void saveChanges(FnMut<void()> done) override;
rpl::producer<bool> desiredShadowVisibility() const override;
private:
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);

View File

@ -81,10 +81,12 @@ public:
void setError(bool error);
rpl::producer<> deleteClicks() const {
return _delete->entity()->clicks();
return _delete->entity()->clicks(
) | rpl::map([] { return rpl::empty_value(); });
}
rpl::producer<> restoreClicks() const {
return _restore->entity()->clicks();
return _restore->entity()->clicks(
) | rpl::map([] { return rpl::empty_value(); });
}
protected:

View File

@ -10,7 +10,6 @@ using "ui/widgets/widgets.style";
using "info/info.style";
using "boxes/boxes.style";
settingsFirstDividerSkip: 3px;
settingsSectionButton: InfoProfileButton(infoProfileButton) {
font: boxTextFont;
padding: margins(79px, 13px, 22px, 11px);
@ -22,7 +21,7 @@ settingsButton: InfoProfileButton(settingsSectionButton) {
padding: margins(22px, 13px, 22px, 11px);
}
settingsSectionSkip: 9px;
settingsSectionIconPosition: point(22px, 9px);
settingsSectionIconLeft: 22px;
settingsSeparatorPadding: margins(22px, infoProfileSkip, 0px, infoProfileSkip);
settingsButtonRightPosition: point(28px, 13px);
settingsButtonRight: FlatLabel(defaultFlatLabel) {
@ -48,7 +47,6 @@ settingsUpdate: InfoProfileButton(infoMainButton, settingsButton) {
settingsUpdateStatePosition: point(24px, 29px);
settingsDividerLabelPadding: margins(22px, 10px, 22px, 19px);
settingsIconSetPhoto: icon {{ "settings_set_photo", menuIconFg }};
settingsIconInformation: icon {{ "settings_information", menuIconFg }};
settingsIconNotifications: icon {{ "settings_notifications", menuIconFg }};
settingsIconChat: icon {{ "settings_chat", menuIconFg }};
@ -68,6 +66,7 @@ settingsLink: boxLinkButton;
settingsAdvancedNotificationsPadding: margins(22px, 20px, 10px, 10px);
settingsLinkLabel: defaultFlatLabel;
settingsCheckboxesSkip: 12px;
settingsStickersEmojiPadding: 17px;
settingsSendType: settingsCheckbox;
settingsSendTypePadding: margins(22px, 5px, 10px, 5px);
@ -100,7 +99,20 @@ settingsCloudPasswordLabel: FlatLabel(defaultFlatLabel) {
}
settingsCloudPasswordLabelPadding: margins(22px, 8px, 10px, 8px);
settingsInfoRowHeight: 62px;
settingsInfoPhotoHeight: 175px;
settingsInfoPhotoSize: 84px;
settingsInfoPhoto: UserpicButton(defaultUserpicButton) {
size: size(settingsInfoPhotoSize, settingsInfoPhotoSize);
photoSize: settingsInfoPhotoSize;
}
settingsInfoPhotoTop: 17px;
settingsInfoPhotoSkip: 16px;
settingsInfoPhotoSet: defaultActiveButton;
settingsInfoRow: InfoProfileButton(settingsButton) {
height: 62px;
padding: margins(0px, 0px, 0px, 0px);
}
settingsInfoIconPosition: point(22px, 18px);
settingsInfoValue: FlatLabel(defaultFlatLabel) {
textFg: windowFg;
@ -114,24 +126,11 @@ settingsInfoAbout: FlatLabel(settingsInfoValue) {
}
settingsInfoAboutPosition: point(78px, 34px);
settingsInfoRightSkip: 60px;
settingsInfoEditPosition: point(0px, 6px);
settingsInfoEdit: IconButton(defaultIconButton) {
width: 56px;
height: 56px;
icon: icon {{ "settings_edit", menuIconFg }};
iconOver: icon {{ "settings_edit", menuIconFgOver }};
iconPosition: point(14px, 14px);
rippleAreaPosition: point(8px, 8px);
rippleAreaSize: 40px;
ripple: RippleAnimation(defaultRippleAnimation) {
color: windowBgOver;
}
}
settingsInfoEditRight: 14px;
settingsInfoEditIconOver: icon {{ "settings_edit", menuIconFgOver }};
settingsBio: InputField(defaultInputField) {
textBg: transparent;
textMargins: margins(2px, 7px, 2px, 0px);
textMargins: margins(0px, 7px, 0px, 13px);
placeholderFg: placeholderFg;
placeholderFgActive: placeholderFgActive;
@ -140,9 +139,6 @@ settingsBio: InputField(defaultInputField) {
placeholderScale: 0.;
placeholderFont: normalFont;
border: 0px;
borderActive: 0px;
heightMin: 32px;
font: boxTextFont;
@ -157,3 +153,4 @@ settingsBioCountdown: FlatLabel(defaultFlatLabel) {
style: boxTextStyle;
textFg: windowSubTextFg;
}
settingsBioLabelPadding: margins(22px, 11px, 22px, 0px);

View File

@ -369,9 +369,10 @@ void DownloadPathRow::setupControls() {
#endif // OS_WIN_STORE
void SetupChatOptions(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container, st::settingsCheckboxesSkip);
void SetupStickersEmoji(not_null<Ui::VerticalLayout*> container) {
AddSkip(container, st::settingsStickersEmojiPadding);
AddSubsectionTitle(container, lng_settings_stickers_emoji);
auto wrap = object_ptr<Ui::VerticalLayout>(container);
const auto inner = wrap.data();
@ -422,65 +423,31 @@ void SetupChatOptions(not_null<Ui::VerticalLayout*> container) {
Local::writeUserSettings();
});
const auto dontask = inner->add(
checkbox(
lng_download_path_dont_ask,
!Global::AskDownloadPath()),
#ifndef OS_WIN_STORE
st::settingsAskPathPadding);
#else // OS_WIN_STORE
st::settingsCheckboxPadding);
#endif // OS_WIN_STORE
#ifndef OS_WIN_STORE
const auto showpath = Ui::AttachAsChild(
dontask,
rpl::event_stream<bool>());
const auto padding = st::settingsDownloadPathPadding;
const auto path = container->add(
object_ptr<Ui::SlideWrap<DownloadPathRow>>(
container,
object_ptr<DownloadPathRow>(container),
QMargins(
(padding.left()
+ st::settingsCheckbox.checkPosition.x()
+ st::defaultCheck.diameter
+ st::settingsCheckbox.textPosition.x()
- st::settingsCheckbox.margin.left()),
padding.top(),
padding.right(),
padding.bottom())));
AddSkip(container, st::settingsCheckboxPadding.bottom());
path->toggleOn(
showpath->events_starting_with(!Global::AskDownloadPath()));
#endif // OS_WIN_STORE
base::ObservableViewer(
dontask->checkedChanged
) | rpl::start_with_next([=](bool checked) {
Global::SetAskDownloadPath(!checked);
Local::writeUserSettings();
#ifndef OS_WIN_STORE
showpath->fire_copy(checked);
#endif // OS_WIN_STORE
}, inner->lifetime());
AddButton(
container,
lng_stickers_you_have,
st::settingsButton
)->addClickHandler([] {
Ui::show(Box<StickersBox>(StickersBox::Section::Installed));
});
AddSkip(container, st::settingsCheckboxesSkip);
}
void SetupSendKey(not_null<Ui::VerticalLayout*> container) {
void SetupChatOther(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
const auto skip = st::settingsSendTypeSkip;
const auto full = st::settingsCheckboxesSkip + skip;
AddSkip(container, full);
AddSkip(container, st::settingsSectionSkip);
AddSubsectionTitle(container, lng_settings_chat_other);
AddSkip(container, st::settingsSendTypeSkip);
enum class SendByType {
Enter,
CtrlEnter,
};
const auto skip = st::settingsSendTypeSkip;
const auto group = std::make_shared<Ui::RadioenumGroup<SendByType>>(
cCtrlEnter() ? SendByType::CtrlEnter : SendByType::Enter);
auto wrap = object_ptr<Ui::VerticalLayout>(container);
@ -491,8 +458,6 @@ void SetupSendKey(not_null<Ui::VerticalLayout*> container) {
std::move(wrap),
QMargins(0, skip, 0, skip)));
AddSkip(container, full);
const auto add = [&](
SendByType value,
LangKey key,
@ -525,11 +490,55 @@ void SetupSendKey(not_null<Ui::VerticalLayout*> container) {
}
Local::writeUserSettings();
});
}
void SetupMediaOptions(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
AddSkip(inner, st::settingsCheckboxesSkip);
const auto dontask = inner->add(
object_ptr<Ui::Checkbox>(
inner,
lang(lng_download_path_dont_ask),
!Global::AskDownloadPath(),
st::settingsCheckbox),
#ifndef OS_WIN_STORE
st::settingsAskPathPadding);
#else // OS_WIN_STORE
st::settingsCheckboxPadding);
#endif // OS_WIN_STORE
#ifndef OS_WIN_STORE
const auto showpath = Ui::AttachAsChild(
dontask,
rpl::event_stream<bool>());
const auto padding = st::settingsDownloadPathPadding;
const auto path = container->add(
object_ptr<Ui::SlideWrap<DownloadPathRow>>(
container,
object_ptr<DownloadPathRow>(container),
QMargins(
(padding.left()
+ st::settingsCheckbox.checkPosition.x()
+ st::defaultCheck.diameter
+ st::settingsCheckbox.textPosition.x()
- st::settingsCheckbox.margin.left()),
padding.top(),
padding.right(),
padding.bottom())));
AddSkip(container, st::settingsCheckboxPadding.bottom());
path->toggleOn(
showpath->events_starting_with(!Global::AskDownloadPath()));
#endif // OS_WIN_STORE
base::ObservableViewer(
dontask->checkedChanged
) | rpl::start_with_next([=](bool checked) {
Global::SetAskDownloadPath(!checked);
Local::writeUserSettings();
#ifndef OS_WIN_STORE
showpath->fire_copy(checked);
#endif // OS_WIN_STORE
}, inner->lifetime());
AddButton(
container,
@ -539,20 +548,12 @@ void SetupMediaOptions(not_null<Ui::VerticalLayout*> container) {
Ui::show(Box<AutoDownloadBox>());
});
AddButton(
container,
lng_stickers_you_have,
st::settingsButton
)->addClickHandler([] {
Ui::show(Box<StickersBox>(StickersBox::Section::Installed));
});
AddSkip(container);
AddSkip(container, st::settingsCheckboxesSkip);
}
void SetupChatBackground(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container, st::settingsCheckboxesSkip);
AddSkip(container, st::settingsSectionSkip);
AddSubsectionTitle(container, lng_settings_section_background);
@ -673,6 +674,8 @@ void SetupThemeOptions(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
AddSubsectionTitle(container, lng_settings_themes);
SetupNightMode(container);
AddButton(
@ -698,12 +701,10 @@ Chat::Chat(QWidget *parent, not_null<UserData*> self)
void Chat::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
AddSkip(content, st::settingsFirstDividerSkip);
SetupChatOptions(content);
SetupSendKey(content);
SetupMediaOptions(content);
SetupStickersEmoji(content);
SetupChatBackground(content);
SetupThemeOptions(content);
SetupChatOther(content);
Ui::ResizeFitChild(this, content);
}

View File

@ -32,17 +32,17 @@ object_ptr<Section> CreateSection(
UserData *self) {
switch (type) {
case Type::Main:
return object_ptr<::Settings::Main>(parent, controller, self);
return object_ptr<Main>(parent, controller, self);
case Type::Information:
return object_ptr<::Settings::Information>(parent, self);
return object_ptr<Information>(parent, controller, self);
case Type::Notifications:
return object_ptr<::Settings::Notifications>(parent, self);
return object_ptr<Notifications>(parent, self);
case Type::PrivacySecurity:
return object_ptr<::Settings::PrivacySecurity>(parent, self);
return object_ptr<PrivacySecurity>(parent, self);
case Type::General:
return object_ptr<::Settings::General>(parent, self);
return object_ptr<General>(parent, self);
case Type::Chat:
return object_ptr<::Settings::Chat>(parent, self);
return object_ptr<Chat>(parent, self);
}
Unexpected("Settings section type in Widget::createInnerWidget.");
}
@ -78,26 +78,36 @@ not_null<Button*> AddButton(
LangKey text,
const style::InfoProfileButton &st,
const style::icon *leftIcon) {
return AddButton(container, Lang::Viewer(text), st, leftIcon);
}
not_null<Button*> AddButton(
not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> text,
const style::InfoProfileButton &st,
const style::icon *leftIcon) {
const auto result = container->add(object_ptr<Button>(
container,
Lang::Viewer(text),
std::move(text),
st));
if (leftIcon) {
const auto icon = Ui::CreateChild<Ui::RpWidget>(result);
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
icon->resize(leftIcon->size());
result->widthValue(
) | rpl::start_with_next([=](int width) {
result->sizeValue(
) | rpl::start_with_next([=](QSize size) {
icon->moveToLeft(
st::settingsSectionIconPosition.x(),
st::settingsSectionIconPosition.y(),
width);
st::settingsSectionIconLeft,
(size.height() - icon->height()) / 2,
size.width());
}, icon->lifetime());
icon->paintRequest(
) | rpl::start_with_next([=] {
Painter p(icon);
const auto width = icon->width();
if (result->isOver()) {
const auto paintOver = (result->isOver() || result->isDown())
&& !result->isDisabled();
if (paintOver) {
leftIcon->paint(p, QPoint(), width, st::menuIconFgOver->c);
} else {
leftIcon->paint(p, QPoint(), width);

View File

@ -75,6 +75,11 @@ not_null<Button*> AddButton(
LangKey text,
const style::InfoProfileButton &st,
const style::icon *leftIcon = nullptr);
not_null<Button*> AddButton(
not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> text,
const style::InfoProfileButton &st,
const style::icon *leftIcon = nullptr);
not_null<Button*> AddButtonWithLabel(
not_null<Ui::VerticalLayout*> container,
LangKey text,

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/checkbox.h"
#include "boxes/local_storage_box.h"
#include "boxes/connection_box.h"
#include "boxes/about_box.h"
@ -68,7 +69,6 @@ void SetupConnectionType(not_null<Ui::VerticalLayout*> container) {
}
void SetupStorageAndConnection(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
AddButton(
@ -230,44 +230,50 @@ bool HasTray() {
return cSupportTray() || (cPlatform() == dbipWindows);
}
void SetupTray(not_null<Ui::VerticalLayout*> container) {
if (!HasTray()) {
return;
}
void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
const auto checkbox = [&](LangKey label, bool checked) {
return object_ptr<Ui::Checkbox>(
container,
lang(label),
checked,
st::settingsCheckbox);
};
const auto addCheckbox = [&](LangKey label, bool checked) {
return container->add(
checkbox(label, checked),
st::settingsCheckboxPadding);
};
const auto addSlidingCheckbox = [&](LangKey label, bool checked) {
return container->add(
object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
container,
checkbox(label, checked),
st::settingsCheckboxPadding));
};
const auto trayEnabler = Ui::AttachAsChild(
container,
rpl::event_stream<bool>());
const auto trayEnabled = [] {
const auto workMode = Global::WorkMode().value();
return (workMode == dbiwmTrayOnly)
|| (workMode == dbiwmWindowAndTray);
};
const auto tray = AddButton(
container,
const auto tray = addCheckbox(
lng_settings_workmode_tray,
st::settingsGeneralButton
)->toggleOn(trayEnabler->events_starting_with(trayEnabled()));
trayEnabled());
const auto taskbarEnabled = [] {
const auto workMode = Global::WorkMode().value();
return (workMode == dbiwmWindowOnly)
|| (workMode == dbiwmWindowAndTray);
};
const auto taskbarEnabler = Ui::AttachAsChild(
container,
rpl::event_stream<bool>());
const auto taskbar = (cPlatform() == dbipWindows)
? AddButton(
container,
? addCheckbox(
lng_settings_workmode_window,
st::settingsGeneralButton
)->toggleOn(taskbarEnabler->events_starting_with(taskbarEnabled()))
taskbarEnabled())
: nullptr;
const auto updateWorkmode = [=] {
const auto newMode = tray->toggled()
? ((!taskbar || taskbar->toggled())
const auto newMode = tray->checked()
? ((!taskbar || taskbar->checked())
? dbiwmWindowAndTray
: dbiwmTrayOnly)
: dbiwmWindowOnly;
@ -279,24 +285,26 @@ void SetupTray(not_null<Ui::VerticalLayout*> container) {
Local::writeSettings();
};
tray->toggledValue(
base::ObservableViewer(
tray->checkedChanged
) | rpl::filter([=](bool checked) {
return (checked != trayEnabled());
}) | rpl::start_with_next([=](bool checked) {
if (!checked && taskbar && !taskbar->toggled()) {
taskbarEnabler->fire(true);
if (!checked && taskbar && !taskbar->checked()) {
taskbar->setChecked(true);
} else {
updateWorkmode();
}
}, tray->lifetime());
if (taskbar) {
taskbar->toggledValue(
base::ObservableViewer(
taskbar->checkedChanged
) | rpl::filter([=](bool checked) {
return (checked != taskbarEnabled());
}) | rpl::start_with_next([=](bool checked) {
if (!checked && !tray->toggled()) {
trayEnabler->fire(true);
if (!checked && !tray->checked()) {
tray->setChecked(true);
} else {
updateWorkmode();
}
@ -305,32 +313,22 @@ void SetupTray(not_null<Ui::VerticalLayout*> container) {
#ifndef OS_WIN_STORE
if (cPlatform() == dbipWindows) {
const auto autostart = AddButton(
container,
lng_settings_auto_start,
st::settingsGeneralButton
)->toggleOn(rpl::single(cAutoStart()));
const auto minimized = container->add(
object_ptr<Ui::SlideWrap<Button>>(
container,
object_ptr<Button>(
container,
Lang::Viewer(lng_settings_start_min),
st::settingsGeneralButton)));
const auto sendto = AddButton(
container,
lng_settings_add_sendto,
st::settingsGeneralButton
)->toggleOn(rpl::single(cSendToMenu()));
const auto minimizedToggler = Ui::AttachAsChild(
minimized,
rpl::event_stream<bool>());
const auto minimizedToggled = [] {
return cStartMinimized() && !Global::LocalPasscode();
};
autostart->toggledValue(
const auto autostart = addCheckbox(
lng_settings_auto_start,
cAutoStart());
const auto minimized = addSlidingCheckbox(
lng_settings_start_min,
minimizedToggled());
const auto sendto = addCheckbox(
lng_settings_add_sendto,
cSendToMenu());
base::ObservableViewer(
autostart->checkedChanged
) | rpl::filter([](bool checked) {
return (checked != cAutoStart());
}) | rpl::start_with_next([=](bool checked) {
@ -338,22 +336,25 @@ void SetupTray(not_null<Ui::VerticalLayout*> container) {
psAutoStart(checked);
if (checked) {
Local::writeSettings();
} else if (minimized->entity()->toggled()) {
minimizedToggler->fire(false);
} else if (minimized->entity()->checked()) {
minimized->entity()->setChecked(false);
} else {
Local::writeSettings();
}
}, autostart->lifetime());
minimized->entity()->toggleOn(
minimizedToggler->events_starting_with(minimizedToggled()));
minimized->toggleOn(autostart->toggledValue());
minimized->entity()->toggledValue(
minimized->toggleOn(rpl::single(
autostart->checked()
) | rpl::then(base::ObservableViewer(
autostart->checkedChanged
)));
base::ObservableViewer(
minimized->entity()->checkedChanged
) | rpl::filter([=](bool checked) {
return (checked != minimizedToggled());
}) | rpl::start_with_next([=](bool checked) {
if (Global::LocalPasscode()) {
minimizedToggler->fire(false);
minimized->entity()->setChecked(false);
Ui::show(Box<InformBox>(
lang(lng_error_start_minimized_passcoded)));
} else {
@ -365,10 +366,11 @@ void SetupTray(not_null<Ui::VerticalLayout*> container) {
base::ObservableViewer(
Global::RefLocalPasscodeChanged()
) | rpl::start_with_next([=] {
minimizedToggler->fire(minimizedToggled());
minimized->entity()->setChecked(minimizedToggled());
}, minimized->lifetime());
sendto->toggledValue(
base::ObservableViewer(
sendto->checkedChanged
) | rpl::filter([](bool checked) {
return (checked != cSendToMenu());
}) | rpl::start_with_next([](bool checked) {
@ -380,6 +382,21 @@ void SetupTray(not_null<Ui::VerticalLayout*> container) {
#endif // OS_WIN_STORE
}
void SetupTray(not_null<Ui::VerticalLayout*> container) {
if (!HasTray()) {
return;
}
auto wrap = object_ptr<Ui::VerticalLayout>(container);
SetupTrayContent(wrap.data());
container->add(object_ptr<Ui::OverrideMargins>(
container,
std::move(wrap)));
AddSkip(container, st::settingsCheckboxesSkip);
}
General::General(QWidget *parent, UserData *self)
: Section(parent) {
setupContent();
@ -388,21 +405,21 @@ General::General(QWidget *parent, UserData *self)
void General::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
AddSkip(content, st::settingsFirstDividerSkip);
if (!Core::UpdaterDisabled()) {
AddDivider(content);
AddSkip(content);
SetupUpdate(content);
AddSkip(content);
}
if (!Core::UpdaterDisabled()) {
AddDivider(content);
}
SetupStorageAndConnection(content);
if (HasTray()) {
AddDivider(content);
AddSkip(content);
SetupTray(content);
AddSkip(content);
}
SetupStorageAndConnection(content);
Ui::ResizeFitChild(this, content);
}

View File

@ -13,34 +13,127 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/popup_menu.h"
#include "ui/special_buttons.h"
#include "boxes/add_contact_box.h"
#include "boxes/confirm_box.h"
#include "boxes/change_phone_box.h"
#include "boxes/photo_crop_box.h"
#include "boxes/username_box.h"
#include "info/profile/info_profile_values.h"
#include "info/profile/info_profile_button.h"
#include "lang/lang_keys.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "core/file_utilities.h"
#include "styles/style_boxes.h"
#include "styles/style_settings.h"
namespace Settings {
namespace {
void SetupPhoto(
not_null<Ui::VerticalLayout*> container,
not_null<Window::Controller*> controller,
not_null<UserData*> self) {
const auto wrap = container->add(object_ptr<BoxContentDivider>(
container,
st::settingsInfoPhotoHeight));
const auto photo = Ui::CreateChild<Ui::UserpicButton>(
wrap,
controller,
self,
Ui::UserpicButton::Role::OpenPhoto,
st::settingsInfoPhoto);
const auto upload = Ui::CreateChild<Ui::RoundButton>(
wrap,
langFactory(lng_settings_upload),
st::settingsInfoPhotoSet);
upload->setFullRadius(true);
upload->addClickHandler([=] {
const auto imageExtensions = cImgExtensions();
const auto filter = qsl("Image files (*")
+ imageExtensions.join(qsl(" *"))
+ qsl(");;")
+ FileDialog::AllFilesFilter();
const auto callback = [=](const FileDialog::OpenResult &result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return;
}
const auto image = result.remoteContent.isEmpty()
? App::readImage(result.paths.front())
: App::readImage(result.remoteContent);
if (image.isNull()
|| image.width() > 10 * image.height()
|| image.height() > 10 * image.width()) {
Ui::show(Box<InformBox>(lang(lng_bad_photo)));
return;
}
auto box = Ui::show(Box<PhotoCropBox>(image, self));
box->ready(
) | rpl::start_with_next([=](QImage &&image) {
Auth().api().uploadPeerPhoto(self, std::move(image));
}, box->lifetime());
};
FileDialog::GetOpenPath(
upload,
lang(lng_choose_image),
filter,
crl::guard(upload, callback));
});
rpl::combine(
wrap->widthValue(),
photo->widthValue(),
upload->widthValue()
) | rpl::start_with_next([=](int max, int photoWidth, int uploadWidth) {
photo->moveToLeft(
(max - photoWidth) / 2,
st::settingsInfoPhotoTop);
upload->moveToLeft(
(max - uploadWidth) / 2,
(st::settingsInfoPhotoTop
+ photo->height()
+ st::settingsInfoPhotoSkip));
}, photo->lifetime());
}
void ShowMenu(
QWidget *parent,
const QString &copyButton,
const QString &text) {
const auto menu = new Ui::PopupMenu(parent);
menu->addAction(copyButton, [=] {
QApplication::clipboard()->setText(text);
});
menu->popup(QCursor::pos());
}
void AddRow(
not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> label,
rpl::producer<TextWithEntities> value,
const QString &copyText,
const style::IconButton &editSt,
const QString &copyButton,
Fn<void()> edit,
const style::icon &icon) {
const auto wrap = container->add(object_ptr<Ui::FixedHeightWidget>(
const auto wrap = AddButton(
container,
st::settingsInfoRowHeight));
wrap->paintRequest(
) | rpl::start_with_next([=, &icon] {
Painter p(wrap);
icon.paint(p, st::settingsInfoIconPosition, wrap->width());
rpl::single(QString()),
st::settingsInfoRow,
&icon);
const auto forcopy = Ui::AttachAsChild(wrap, QString());
wrap->setAcceptBoth();
wrap->clicks(
) | rpl::filter([=] {
return !wrap->isDisabled();
}) | rpl::start_with_next([=](Qt::MouseButton button) {
if (button == Qt::LeftButton) {
edit();
} else if (!forcopy->isEmpty()) {
ShowMenu(wrap, copyButton, *forcopy);
}
}, wrap->lifetime());
auto existing = base::duplicate(
@ -48,8 +141,15 @@ void AddRow(
) | rpl::map([](const TextWithEntities &text) {
return text.entities.isEmpty();
});
base::duplicate(
value
) | rpl::filter([](const TextWithEntities &text) {
return text.entities.isEmpty();
}) | rpl::start_with_next([=](const TextWithEntities &text) {
*forcopy = text.text;
}, wrap->lifetime());
const auto text = Ui::CreateChild<Ui::FlatLabel>(
wrap,
wrap.get(),
std::move(value),
st::settingsInfoValue);
text->setClickHandlerFilter([=](auto&&...) {
@ -59,24 +159,32 @@ void AddRow(
base::duplicate(
existing
) | rpl::start_with_next([=](bool existing) {
wrap->setDisabled(!existing);
text->setAttribute(Qt::WA_TransparentForMouseEvents, existing);
text->setSelectable(existing);
text->setDoubleClickSelectsParagraph(existing);
text->setContextCopyText(existing ? copyText : QString());
}, text->lifetime());
const auto about = Ui::CreateChild<Ui::FlatLabel>(
wrap,
wrap.get(),
std::move(label),
st::settingsInfoAbout);
about->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto button = Ui::CreateChild<Ui::IconButton>(
wrap,
editSt);
button->addClickHandler(edit);
button->showOn(std::move(existing));
const auto button = Ui::CreateChild<Ui::RpWidget>(wrap.get());
button->resize(st::settingsInfoEditIconOver.size());
button->setAttribute(Qt::WA_TransparentForMouseEvents);
button->paintRequest(
) | rpl::filter([=] {
return (wrap->isOver() || wrap->isDown()) && !wrap->isDisabled();
}) | rpl::start_with_next([=](QRect clip) {
Painter p(button);
st::settingsInfoEditIconOver.paint(p, QPoint(), button->width());
}, button->lifetime());
wrap->widthValue(
) | rpl::start_with_next([=](int width) {
wrap->sizeValue(
) | rpl::start_with_next([=](QSize size) {
const auto width = size.width();
text->resizeToWidth(width
- st::settingsInfoValuePosition.x()
- st::settingsInfoRightSkip);
@ -92,8 +200,8 @@ void AddRow(
st::settingsInfoAboutPosition.y(),
width);
button->moveToRight(
st::settingsInfoEditPosition.x(),
st::settingsInfoEditPosition.y(),
st::settingsInfoEditRight,
(size.height() - button->height()) / 2,
width);
}, wrap->lifetime());
}
@ -101,7 +209,6 @@ void AddRow(
void SetupRows(
not_null<Ui::VerticalLayout*> container,
not_null<UserData*> self) {
AddDivider(container);
AddSkip(container);
AddRow(
@ -109,7 +216,6 @@ void SetupRows(
Lang::Viewer(lng_settings_name_label),
Info::Profile::NameValue(self),
lang(lng_profile_copy_fullname),
st::settingsInfoEdit,
[=] { Ui::show(Box<EditNameBox>(self)); },
st::settingsInfoName);
@ -118,7 +224,6 @@ void SetupRows(
Lang::Viewer(lng_settings_phone_label),
Info::Profile::PhoneValue(self),
lang(lng_profile_copy_phone),
st::settingsInfoEdit,
[] { Ui::show(Box<ChangePhoneBox>()); },
st::settingsInfoPhone);
@ -154,7 +259,6 @@ void SetupRows(
std::move(label),
std::move(value),
lang(lng_context_copy_mention),
st::settingsInfoEdit,
[=] { Ui::show(Box<UsernameBox>()); },
st::settingsInfoUsername);
@ -257,8 +361,14 @@ BioManager SetupBio(
bio->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
updated();
container->add(
object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(lng_settings_about_bio),
st::boxDividerLabel),
st::settingsBioLabelPadding);
AddSkip(container);
AddDividerText(container, Lang::Viewer(lng_settings_about_bio));
return BioManager{
changed->events() | rpl::distinct_until_changed(),
@ -268,10 +378,13 @@ BioManager SetupBio(
} // namespace
Information::Information(QWidget *parent, not_null<UserData*> self)
Information::Information(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<UserData*> self)
: Section(parent)
, _self(self) {
setupContent();
setupContent(controller);
}
rpl::producer<bool> Information::sectionCanSaveChanges() {
@ -282,10 +395,10 @@ void Information::sectionSaveChanges(FnMut<void()> done) {
_save(std::move(done));
}
void Information::setupContent() {
void Information::setupContent(not_null<Window::Controller*> controller) {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
AddSkip(content, st::settingsFirstDividerSkip);
SetupPhoto(content, controller, _self);
SetupRows(content, _self);
auto manager = SetupBio(content, _self);
_canSaveChanges = std::move(manager.canSave);

View File

@ -13,13 +13,16 @@ namespace Settings {
class Information : public Section {
public:
Information(QWidget *parent, not_null<UserData*> self);
Information(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<UserData*> self);
rpl::producer<bool> sectionCanSaveChanges() override;
void sectionSaveChanges(FnMut<void()> done) override;
private:
void setupContent();
void setupContent(not_null<Window::Controller*> controller);
not_null<UserData*> _self;
rpl::variable<bool> _canSaveChanges;

View File

@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/language_box.h"
#include "boxes/confirm_box.h"
#include "boxes/about_box.h"
#include "boxes/photo_crop_box.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/discrete_sliders.h"
@ -27,58 +26,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Settings {
void SetupUploadPhotoButton(
not_null<Ui::VerticalLayout*> container,
not_null<UserData*> self) {
AddDivider(container);
AddSkip(container, st::settingsSetPhotoSkip);
const auto upload = [=] {
const auto imageExtensions = cImgExtensions();
const auto filter = qsl("Image files (*")
+ imageExtensions.join(qsl(" *"))
+ qsl(");;")
+ FileDialog::AllFilesFilter();
const auto callback = [=](const FileDialog::OpenResult &result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return;
}
const auto image = result.remoteContent.isEmpty()
? App::readImage(result.paths.front())
: App::readImage(result.remoteContent);
if (image.isNull()
|| image.width() > 10 * image.height()
|| image.height() > 10 * image.width()) {
Ui::show(Box<InformBox>(lang(lng_bad_photo)));
return;
}
auto box = Ui::show(Box<PhotoCropBox>(image, self));
box->ready(
) | rpl::start_with_next([=](QImage &&image) {
Auth().api().uploadPeerPhoto(self, std::move(image));
}, box->lifetime());
};
FileDialog::GetOpenPath(
container.get(),
lang(lng_choose_image),
filter,
crl::guard(container, callback));
};
AddButton(
container,
lng_settings_upload,
st::settingsSectionButton,
&st::settingsIconSetPhoto
)->addClickHandler(App::LambdaDelayed(
st::settingsSectionButton.ripple.hideDuration,
container,
upload));
AddSkip(container, st::settingsSetPhotoSkip);
}
void SetupLanguageButton(not_null<Ui::VerticalLayout*> container) {
const auto button = AddButtonWithLabel(
container,
@ -121,14 +68,14 @@ void SetupSections(
lng_settings_section_privacy,
Type::PrivacySecurity,
&st::settingsIconPrivacySecurity);
addSection(
lng_settings_section_general,
Type::General,
&st::settingsIconGeneral);
addSection(
lng_settings_section_chat_settings,
Type::Chat,
&st::settingsIconChat);
addSection(
lng_settings_advanced,
Type::General,
&st::settingsIconGeneral);
SetupLanguageButton(container);
@ -309,7 +256,6 @@ void Main::setupContent(not_null<Window::Controller*> controller) {
controller));
cover->setOnlineCount(rpl::single(0));
SetupUploadPhotoButton(content, _self);
SetupSections(content, [=](Type type) {
_showOther.fire_copy(type);
});

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "lang/lang_keys.h"
#include "info/profile/info_profile_button.h"
#include "storage/localstorage.h"
#include "window/notifications_manager.h"
#include "boxes/notifications_box.h"
@ -74,15 +75,26 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
const auto native = nativeNotificationsKey
? addCheckbox(nativeNotificationsKey, Global::NativeNotifications())
: nullptr;
const auto advanced = (cPlatform() != dbipMac)
const auto advancedSlide = (cPlatform() != dbipMac)
? container->add(
object_ptr<Ui::SlideWrap<Ui::LinkButton>>(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container,
object_ptr<Ui::LinkButton>(
container,
lang(lng_settings_advanced_notifications),
st::settingsLink),
st::settingsAdvancedNotificationsPadding))
object_ptr<Ui::VerticalLayout>(container)))
: nullptr;
const auto advancedWrap = advancedSlide
? advancedSlide->entity()
: nullptr;
if (advancedWrap) {
AddSkip(advancedWrap, st::settingsCheckboxesSkip);
AddDivider(advancedWrap);
AddSkip(advancedWrap, st::settingsCheckboxesSkip);
}
const auto advanced = advancedWrap
? AddButton(
advancedWrap,
lng_settings_advanced_notifications,
st::settingsButton).get()
: nullptr;
if (!name->entity()->checked()) {
@ -92,8 +104,8 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
name->hide(anim::type::instant);
preview->hide(anim::type::instant);
}
if (native && advanced && Global::NativeNotifications()) {
advanced->hide(anim::type::instant);
if (native && advancedSlide && Global::NativeNotifications()) {
advancedSlide->hide(anim::type::instant);
}
using Change = Window::Notifications::ChangeType;
@ -187,22 +199,21 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
Auth().notifications().createManager();
if (advanced) {
advanced->toggle(
if (advancedSlide) {
advancedSlide->toggle(
!Global::NativeNotifications(),
anim::type::normal);
}
}, native->lifetime());
}
if (advanced) {
advanced->entity()->addClickHandler([=] {
advanced->addClickHandler([=] {
Ui::show(Box<NotificationsBox>());
});
}
}
void SetupNotifications(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container, st::settingsCheckboxesSkip);
auto wrap = object_ptr<Ui::VerticalLayout>(container);
@ -226,7 +237,6 @@ Notifications::Notifications(QWidget *parent, not_null<UserData*> self)
void Notifications::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
AddSkip(content, st::settingsFirstDividerSkip);
SetupNotifications(content);
Ui::ResizeFitChild(this, content);

View File

@ -57,7 +57,6 @@ QString PrivacyBase(ApiWrap::Privacy::Option option) {
}
void SetupPrivacy(not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
AddSubsectionTitle(container, lng_settings_privacy_title);
@ -482,7 +481,6 @@ PrivacySecurity::PrivacySecurity(QWidget *parent, not_null<UserData*> self)
void PrivacySecurity::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
AddSkip(content, st::settingsFirstDividerSkip);
SetupPrivacy(content);
SetupSecurity(content);
SetupCalls(content);

View File

@ -78,7 +78,7 @@ void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
emit clicked();
}
if (weak) {
_clicks.fire({});
_clicks.fire(e->button());
}
} else {
setOver(false, StateChangeSource::ByHover);

View File

@ -43,7 +43,7 @@ public:
_clickedCallback = std::move(callback);
}
rpl::producer<> clicks() const {
rpl::producer<Qt::MouseButton> clicks() const {
return _clicks.events();
}
template <typename Handler>
@ -100,7 +100,7 @@ private:
Fn<void()> _clickedCallback;
rpl::event_stream<> _clicks;
rpl::event_stream<Qt::MouseButton> _clicks;
};

View File

@ -266,6 +266,11 @@ void RoundButton::setFullWidth(int newFullWidth) {
refreshText();
}
void RoundButton::setFullRadius(bool enabled) {
_fullRadius = enabled;
update();
}
void RoundButton::refreshText() {
_text = computeFullText();
_textWidth = _text.isEmpty() ? 0 : _st.font->width(_text);
@ -319,12 +324,24 @@ void RoundButton::paintEvent(QPaintEvent *e) {
if (_fullWidthOverride < 0) {
rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height());
}
App::roundRect(p, myrtlrect(rounded), _st.textBg, ImageRoundRadius::Small);
const auto drawRect = [&](const style::color &color) {
const auto fill = myrtlrect(rounded);
if (_fullRadius) {
const auto radius = rounded.height() / 2;
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(color);
p.drawRoundedRect(fill, radius, radius);
} else {
App::roundRect(p, fill, color, ImageRoundRadius::Small);
}
};
drawRect(_st.textBg);
auto over = isOver();
auto down = isDown();
if (over || down) {
App::roundRect(p, myrtlrect(rounded), _st.textBgOver, ImageRoundRadius::Small);
drawRect(_st.textBgOver);
}
auto ms = getms();
@ -369,7 +386,9 @@ QImage RoundButton::prepareRippleMask() const {
if (_fullWidthOverride < 0) {
rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height());
}
return RippleAnimation::roundRectMask(rounded.size(), st::buttonRadius);
return RippleAnimation::roundRectMask(
rounded.size(),
_fullRadius ? (rounded.height() / 2) : st::buttonRadius);
}
QPoint RoundButton::prepareRippleStartPosition() const {

View File

@ -120,6 +120,7 @@ public:
int contentWidth() const;
void setFullWidth(int newFullWidth);
void setFullRadius(bool enabled);
enum class TextTransform {
NoTransform,
@ -153,6 +154,7 @@ private:
const style::RoundButton &_st;
TextTransform _transform = TextTransform::ToUpper;
bool _fullRadius = false;
};

View File

@ -87,13 +87,15 @@ void SeparatePanel::updateTitlePosition() {
rpl::producer<> SeparatePanel::backRequests() const {
return rpl::merge(
_back->entity()->clicks(),
_back->entity()->clicks(
) | rpl::map([] { return rpl::empty_value(); }),
_synteticBackRequests.events());
}
rpl::producer<> SeparatePanel::closeRequests() const {
return rpl::merge(
_close->clicks(),
_close->clicks(
) | rpl::map([] { return rpl::empty_value(); }),
_userCloseRequests.events());
}

View File

@ -293,11 +293,15 @@ void TermsBox::prepare() {
return false;
}
return true;
}) | rpl::map([] {
return rpl::empty_value();
}) | rpl::start_to_stream(_agreeClicks, lifetime());
if (_cancel) {
addButton(_cancel, [=] {})->clicks(
) | rpl::start_to_stream(_cancelClicks, lifetime());
) | rpl::map([] {
return rpl::empty_value();
}) | rpl::start_to_stream(_cancelClicks, lifetime());
}
if (age) {