2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 06:35:14 +00:00

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

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);