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:
@@ -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 ©Button,
|
||||
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 ©Text,
|
||||
const style::IconButton &editSt,
|
||||
const QString ©Button,
|
||||
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);
|
||||
|
Reference in New Issue
Block a user