Refactor Ui::Radiobutton. Add Ui::Radioenum<Enum>.

Now group of Ui::Radiobutton instances share Ui::RadiobuttonGroup.
All value management is done through the group instance, not through
separate radio buttons. Also a template for groups over enums added.
This commit is contained in:
John Preston 2017-03-19 00:06:10 +03:00
parent 0a40bf2071
commit 12cbf78191
17 changed files with 247 additions and 170 deletions

View file

@ -197,7 +197,7 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
auto &v = d.vimported.v; auto &v = d.vimported.v;
UserData *user = nullptr; UserData *user = nullptr;
if (!v.isEmpty()) { if (!v.isEmpty()) {
const auto &c(v.front().c_importedContact()); auto &c = v.front().c_importedContact();
if (c.vclient_id.v != _contactId) return; if (c.vclient_id.v != _contactId) return;
user = App::userLoaded(c.vuser_id.v); user = App::userLoaded(c.vuser_id.v);
@ -419,8 +419,9 @@ void GroupInfoBox::onPhotoReady(const QImage &img) {
SetupChannelBox::SetupChannelBox(QWidget*, ChannelData *channel, bool existing) SetupChannelBox::SetupChannelBox(QWidget*, ChannelData *channel, bool existing)
: _channel(channel) : _channel(channel)
, _existing(existing) , _existing(existing)
, _public(this, qsl("channel_privacy"), 0, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), true, st::defaultBoxCheckbox) , _privacyGroup(std::make_shared<Ui::RadioenumGroup<Privacy>>(Privacy::Public))
, _private(this, qsl("channel_privacy"), 1, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), false, st::defaultBoxCheckbox) , _public(this, _privacyGroup, Privacy::Public, lang(channel->isMegagroup() ? lng_create_public_group_title : lng_create_public_channel_title), st::defaultBoxCheckbox)
, _private(this, _privacyGroup, Privacy::Private, lang(channel->isMegagroup() ? lng_create_private_group_title : lng_create_private_channel_title), st::defaultBoxCheckbox)
, _aboutPublicWidth(st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultBoxCheckbox.textPosition.x()) , _aboutPublicWidth(st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right() - st::newGroupPadding.left() - st::defaultBoxCheckbox.textPosition.x())
, _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth) , _aboutPublic(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_public_group_about : lng_create_public_channel_about), _defaultOptions, _aboutPublicWidth)
, _aboutPrivate(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth) , _aboutPrivate(st::defaultTextStyle, lang(channel->isMegagroup() ? lng_create_private_group_about : lng_create_private_channel_about), _defaultOptions, _aboutPublicWidth)
@ -438,13 +439,12 @@ void SetupChannelBox::prepare() {
addButton(lang(_existing ? lng_cancel : lng_create_group_skip), [this] { closeBox(); }); addButton(lang(_existing ? lng_cancel : lng_create_group_skip), [this] { closeBox(); });
connect(_link, SIGNAL(changed()), this, SLOT(onChange())); connect(_link, SIGNAL(changed()), this, SLOT(onChange()));
_link->setVisible(_public->checked()); _link->setVisible(_privacyGroup->value() == Privacy::Public);
_checkTimer.setSingleShot(true); _checkTimer.setSingleShot(true);
connect(&_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck())); connect(&_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck()));
connect(_public, SIGNAL(changed()), this, SLOT(onPrivacyChange())); _privacyGroup->setChangedCallback([this](Privacy value) { privacyChanged(value); });
connect(_private, SIGNAL(changed()), this, SLOT(onPrivacyChange()));
updateMaxHeight(); updateMaxHeight();
} }
@ -459,7 +459,7 @@ void SetupChannelBox::setInnerFocus() {
void SetupChannelBox::updateMaxHeight() { void SetupChannelBox::updateMaxHeight() {
auto newHeight = st::boxPadding.top() + st::newGroupPadding.top() + _public->heightNoMargins() + _aboutPublicHeight + st::newGroupSkip + _private->heightNoMargins() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom(); auto newHeight = st::boxPadding.top() + st::newGroupPadding.top() + _public->heightNoMargins() + _aboutPublicHeight + st::newGroupSkip + _private->heightNoMargins() + _aboutPrivate.countHeight(_aboutPublicWidth) + st::newGroupSkip + st::newGroupPadding.bottom();
if (!_channel->isMegagroup() || _public->checked()) { if (!_channel->isMegagroup() || _privacyGroup->value() == Privacy::Public) {
newHeight += st::newGroupLinkPadding.top() + _link->height() + st::newGroupLinkPadding.bottom(); newHeight += st::newGroupLinkPadding.top() + _link->height() + st::newGroupLinkPadding.bottom();
} }
setDimensions(st::boxWideWidth, newHeight); setDimensions(st::boxWideWidth, newHeight);
@ -563,7 +563,7 @@ void SetupChannelBox::closeHook() {
} }
void SetupChannelBox::onSave() { void SetupChannelBox::onSave() {
if (!_public->checked()) { if (_privacyGroup->value() == Privacy::Private) {
if (_existing) { if (_existing) {
_sentUsername = QString(); _sentUsername = QString();
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail)); _saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
@ -633,13 +633,13 @@ void SetupChannelBox::onCheck() {
} }
} }
void SetupChannelBox::onPrivacyChange() { void SetupChannelBox::privacyChanged(Privacy value) {
if (_public->checked()) { if (value == Privacy::Public) {
if (_tooMuchUsernames) { if (_tooMuchUsernames) {
_private->setChecked(true); _privacyGroup->setValue(Privacy::Private);
Ui::show(Box<RevokePublicLinkBox>(base::lambda_guarded(this, [this] { Ui::show(Box<RevokePublicLinkBox>(base::lambda_guarded(this, [this] {
_tooMuchUsernames = false; _tooMuchUsernames = false;
_public->setChecked(true); _privacyGroup->setValue(Privacy::Public);
onCheck(); onCheck();
})), KeepOtherLayers); })), KeepOtherLayers);
return; return;
@ -712,8 +712,7 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
showRevokePublicLinkBoxForEdit(); showRevokePublicLinkBoxForEdit();
} else { } else {
_tooMuchUsernames = true; _tooMuchUsernames = true;
_private->setChecked(true); _privacyGroup->setValue(Privacy::Private);
onPrivacyChange();
} }
return true; return true;
} else if (err == qstr("USERNAME_INVALID")) { } else if (err == qstr("USERNAME_INVALID")) {
@ -750,8 +749,7 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) {
showRevokePublicLinkBoxForEdit(); showRevokePublicLinkBoxForEdit();
} else { } else {
_tooMuchUsernames = true; _tooMuchUsernames = true;
_private->setChecked(true); _privacyGroup->setValue(Privacy::Private);
onPrivacyChange();
} }
return true; return true;
} }

View file

@ -31,7 +31,10 @@ class PhoneInput;
class InputArea; class InputArea;
class UsernameInput; class UsernameInput;
class Checkbox; class Checkbox;
class Radiobutton; template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
class LinkButton; class LinkButton;
class NewAvatarButton; class NewAvatarButton;
} // namespace Ui } // namespace Ui
@ -150,9 +153,12 @@ private slots:
void onChange(); void onChange();
void onCheck(); void onCheck();
void onPrivacyChange();
private: private:
enum class Privacy {
Public,
Private,
};
void privacyChanged(Privacy value);
void updateSelected(const QPoint &cursorGlobalPosition); void updateSelected(const QPoint &cursorGlobalPosition);
void onUpdateDone(const MTPBool &result); void onUpdateDone(const MTPBool &result);
@ -169,8 +175,9 @@ private:
ChannelData *_channel = nullptr; ChannelData *_channel = nullptr;
bool _existing = false; bool _existing = false;
object_ptr<Ui::Radiobutton> _public; std::shared_ptr<Ui::RadioenumGroup<Privacy>> _privacyGroup;
object_ptr<Ui::Radiobutton> _private; object_ptr<Ui::Radioenum<Privacy>> _public;
object_ptr<Ui::Radioenum<Privacy>> _private;
int32 _aboutPublicWidth, _aboutPublicHeight; int32 _aboutPublicWidth, _aboutPublicHeight;
Text _aboutPublic, _aboutPrivate; Text _aboutPublic, _aboutPrivate;

View file

@ -34,31 +34,27 @@ void AutoLockBox::prepare() {
addButton(lang(lng_box_ok), [this] { closeBox(); }); addButton(lang(lng_box_ok), [this] { closeBox(); });
int opts[] = { 60, 300, 3600, 18000 }, cnt = sizeof(opts) / sizeof(opts[0]); auto options = { 60, 300, 3600, 18000 };
auto group = std::make_shared<Ui::RadiobuttonGroup>(Global::AutoLock());
auto y = st::boxOptionListPadding.top(); auto y = st::boxOptionListPadding.top();
_options.reserve(cnt); auto count = int(options.size());
for (auto i = 0; i != cnt; ++i) { _options.reserve(count);
auto v = opts[i]; for (auto seconds : options) {
_options.push_back(new Ui::Radiobutton(this, qsl("autolock"), v, (v % 3600) ? lng_passcode_autolock_minutes(lt_count, v / 60) : lng_passcode_autolock_hours(lt_count, v / 3600), (Global::AutoLock() == v), st::langsButton)); _options.emplace_back(this, group, seconds, (seconds % 3600) ? lng_passcode_autolock_minutes(lt_count, seconds / 60) : lng_passcode_autolock_hours(lt_count, seconds / 3600), st::langsButton);
_options.back()->move(st::boxPadding.left() + st::boxOptionListPadding.left(), y); _options.back()->move(st::boxPadding.left() + st::boxOptionListPadding.left(), y);
y += _options.back()->heightNoMargins() + st::boxOptionListSkip; y += _options.back()->heightNoMargins() + st::boxOptionListSkip;
connect(_options.back(), SIGNAL(changed()), this, SLOT(onChange()));
} }
group->setChangedCallback([this](int value) { durationChanged(value); });
setDimensions(st::langsWidth, st::boxOptionListPadding.top() + cnt * st::langsButton.height + (cnt - 1) * st::boxOptionListSkip + st::boxOptionListPadding.bottom() + st::boxPadding.bottom()); setDimensions(st::langsWidth, st::boxOptionListPadding.top() + count * st::langsButton.height + (count - 1) * st::boxOptionListSkip + st::boxOptionListPadding.bottom() + st::boxPadding.bottom());
} }
void AutoLockBox::onChange() { void AutoLockBox::durationChanged(int seconds) {
if (!isBoxShown()) return; Global::SetAutoLock(seconds);
Local::writeUserSettings();
Global::RefLocalPasscodeChanged().notify();
for (int32 i = 0, l = _options.size(); i < l; ++i) {
int32 v = _options[i]->val();
if (_options[i]->checked()) {
Global::SetAutoLock(v);
Local::writeUserSettings();
Global::RefLocalPasscodeChanged().notify();
}
}
App::wnd()->checkAutoLock(); App::wnd()->checkAutoLock();
closeBox(); closeBox();
} }

View file

@ -36,10 +36,9 @@ public:
protected: protected:
void prepare() override; void prepare() override;
private slots:
void onChange();
private: private:
QVector<Ui::Radiobutton*> _options; void durationChanged(int seconds);
std::vector<object_ptr<Ui::Radiobutton>> _options;
}; };

View file

@ -35,9 +35,10 @@ ConnectionBox::ConnectionBox(QWidget *parent)
, _portInput(this, st::connectionPortInputField, lang(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port)) , _portInput(this, st::connectionPortInputField, lang(lng_connection_port_ph), QString::number(Global::ConnectionProxy().port))
, _userInput(this, st::connectionUserInputField, lang(lng_connection_user_ph), Global::ConnectionProxy().user) , _userInput(this, st::connectionUserInputField, lang(lng_connection_user_ph), Global::ConnectionProxy().user)
, _passwordInput(this, st::connectionPasswordInputField, lang(lng_connection_password_ph), Global::ConnectionProxy().password) , _passwordInput(this, st::connectionPasswordInputField, lang(lng_connection_password_ph), Global::ConnectionProxy().password)
, _autoRadio(this, qsl("conn_type"), dbictAuto, lang(lng_connection_auto_rb), (Global::ConnectionType() == dbictAuto), st::defaultBoxCheckbox) , _typeGroup(std::make_shared<Ui::RadioenumGroup<DBIConnectionType>>(Global::ConnectionType()))
, _httpProxyRadio(this, qsl("conn_type"), dbictHttpProxy, lang(lng_connection_http_proxy_rb), (Global::ConnectionType() == dbictHttpProxy), st::defaultBoxCheckbox) , _autoRadio(this, _typeGroup, dbictAuto, lang(lng_connection_auto_rb), st::defaultBoxCheckbox)
, _tcpProxyRadio(this, qsl("conn_type"), dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), (Global::ConnectionType() == dbictTcpProxy), st::defaultBoxCheckbox) , _httpProxyRadio(this, _typeGroup, dbictHttpProxy, lang(lng_connection_http_proxy_rb), st::defaultBoxCheckbox)
, _tcpProxyRadio(this, _typeGroup, dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), st::defaultBoxCheckbox)
, _tryIPv6(this, lang(lng_connection_try_ipv6), Global::TryIPv6(), st::defaultBoxCheckbox) { , _tryIPv6(this, lang(lng_connection_try_ipv6), Global::TryIPv6(), st::defaultBoxCheckbox) {
} }
@ -47,9 +48,7 @@ void ConnectionBox::prepare() {
addButton(lang(lng_connection_save), [this] { onSave(); }); addButton(lang(lng_connection_save), [this] { onSave(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
connect(_autoRadio, SIGNAL(changed()), this, SLOT(onChange())); _typeGroup->setChangedCallback([this](DBIConnectionType value) { typeChanged(value); });
connect(_httpProxyRadio, SIGNAL(changed()), this, SLOT(onChange()));
connect(_tcpProxyRadio, SIGNAL(changed()), this, SLOT(onChange()));
connect(_hostInput, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); connect(_hostInput, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
connect(_portInput, SIGNAL(submitted(bool)), this, SLOT(onSubmit())); connect(_portInput, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
@ -61,17 +60,17 @@ void ConnectionBox::prepare() {
void ConnectionBox::updateControlsVisibility() { void ConnectionBox::updateControlsVisibility() {
auto newHeight = st::boxOptionListPadding.top() + _autoRadio->heightNoMargins() + st::boxOptionListSkip + _httpProxyRadio->heightNoMargins() + st::boxOptionListSkip + _tcpProxyRadio->heightNoMargins() + st::boxOptionListSkip + st::connectionIPv6Skip + _tryIPv6->heightNoMargins() + st::boxOptionListPadding.bottom() + st::boxPadding.bottom(); auto newHeight = st::boxOptionListPadding.top() + _autoRadio->heightNoMargins() + st::boxOptionListSkip + _httpProxyRadio->heightNoMargins() + st::boxOptionListSkip + _tcpProxyRadio->heightNoMargins() + st::boxOptionListSkip + st::connectionIPv6Skip + _tryIPv6->heightNoMargins() + st::boxOptionListPadding.bottom() + st::boxPadding.bottom();
if (_httpProxyRadio->checked() || _tcpProxyRadio->checked()) { if (_typeGroup->value() == dbictAuto) {
_hostInput->hide();
_portInput->hide();
_userInput->hide();
_passwordInput->hide();
} else {
newHeight += 2 * st::boxOptionInputSkip + 2 * _hostInput->height(); newHeight += 2 * st::boxOptionInputSkip + 2 * _hostInput->height();
_hostInput->show(); _hostInput->show();
_portInput->show(); _portInput->show();
_userInput->show(); _userInput->show();
_passwordInput->show(); _passwordInput->show();
} else {
_hostInput->hide();
_portInput->hide();
_userInput->hide();
_passwordInput->hide();
} }
setDimensions(st::boxWidth, newHeight); setDimensions(st::boxWidth, newHeight);
@ -93,16 +92,17 @@ void ConnectionBox::resizeEvent(QResizeEvent *e) {
} }
void ConnectionBox::updateControlsPosition() { void ConnectionBox::updateControlsPosition() {
auto type = _typeGroup->value();
_autoRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top()); _autoRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top());
_httpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _autoRadio->bottomNoMargins() + st::boxOptionListSkip); _httpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _autoRadio->bottomNoMargins() + st::boxOptionListSkip);
int32 inputy = 0; auto inputy = 0;
if (_httpProxyRadio->checked()) { if (type == dbictHttpProxy) {
inputy = _httpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip; inputy = _httpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip;
_tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), inputy + st::boxOptionInputSkip + 2 * _hostInput->height() + st::boxOptionListSkip); _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), inputy + st::boxOptionInputSkip + 2 * _hostInput->height() + st::boxOptionListSkip);
} else { } else {
_tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _httpProxyRadio->bottomNoMargins() + st::boxOptionListSkip); _tcpProxyRadio->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _httpProxyRadio->bottomNoMargins() + st::boxOptionListSkip);
if (_tcpProxyRadio->checked()) { if (type == dbictTcpProxy) {
inputy = _tcpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip; inputy = _tcpProxyRadio->bottomNoMargins() + st::boxOptionInputSkip;
} }
} }
@ -114,17 +114,17 @@ void ConnectionBox::updateControlsPosition() {
_passwordInput->moveToRight(st::boxPadding.right(), _userInput->y()); _passwordInput->moveToRight(st::boxPadding.right(), _userInput->y());
} }
auto tryipv6y = (_tcpProxyRadio->checked() ? _userInput->bottomNoMargins() : _tcpProxyRadio->bottomNoMargins()) + st::boxOptionListSkip + st::connectionIPv6Skip; auto tryipv6y = ((type == dbictTcpProxy) ? _userInput->bottomNoMargins() : _tcpProxyRadio->bottomNoMargins()) + st::boxOptionListSkip + st::connectionIPv6Skip;
_tryIPv6->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), tryipv6y); _tryIPv6->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), tryipv6y);
} }
void ConnectionBox::onChange() { void ConnectionBox::typeChanged(DBIConnectionType type) {
updateControlsVisibility(); updateControlsVisibility();
if (_httpProxyRadio->checked() || _tcpProxyRadio->checked()) { if (type != dbictAuto) {
if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && !_passwordInput->hasFocus()) { if (!_hostInput->hasFocus() && !_portInput->hasFocus() && !_userInput->hasFocus() && !_passwordInput->hasFocus()) {
_hostInput->setFocusFast(); _hostInput->setFocusFast();
} }
if (_httpProxyRadio->checked() && !_portInput->getLastText().toInt()) { if ((type == dbictHttpProxy) && !_portInput->getLastText().toInt()) {
_portInput->setText(qsl("80")); _portInput->setText(qsl("80"));
_portInput->finishAnimations(); _portInput->finishAnimations();
} }
@ -161,7 +161,15 @@ void ConnectionBox::onSubmit() {
} }
void ConnectionBox::onSave() { void ConnectionBox::onSave() {
if (_httpProxyRadio->checked() || _tcpProxyRadio->checked()) { auto type = _typeGroup->value();
if (type == dbictAuto) {
Global::SetConnectionType(type);
Global::SetConnectionProxy(ProxyData());
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
QNetworkProxyFactory::setUseSystemConfiguration(false);
QNetworkProxyFactory::setUseSystemConfiguration(true);
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
} else {
ProxyData p; ProxyData p;
p.host = _hostInput->getLastText().trimmed(); p.host = _hostInput->getLastText().trimmed();
p.user = _userInput->getLastText().trimmed(); p.user = _userInput->getLastText().trimmed();
@ -174,19 +182,8 @@ void ConnectionBox::onSave() {
_portInput->setFocus(); _portInput->setFocus();
return; return;
} }
if (_httpProxyRadio->checked()) { Global::SetConnectionType(type);
Global::SetConnectionType(dbictHttpProxy);
} else {
Global::SetConnectionType(dbictTcpProxy);
}
Global::SetConnectionProxy(p); Global::SetConnectionProxy(p);
} else {
Global::SetConnectionType(dbictAuto);
Global::SetConnectionProxy(ProxyData());
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
QNetworkProxyFactory::setUseSystemConfiguration(false);
QNetworkProxyFactory::setUseSystemConfiguration(true);
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
} }
if (cPlatform() == dbipWindows && Global::TryIPv6() != _tryIPv6->checked()) { if (cPlatform() == dbipWindows && Global::TryIPv6() != _tryIPv6->checked()) {
Global::SetTryIPv6(_tryIPv6->checked()); Global::SetTryIPv6(_tryIPv6->checked());

View file

@ -27,7 +27,10 @@ class InputField;
class PortInput; class PortInput;
class PasswordInput; class PasswordInput;
class Checkbox; class Checkbox;
class Radiobutton; template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
} // namespace Ui } // namespace Ui
class ConnectionBox : public BoxContent { class ConnectionBox : public BoxContent {
@ -43,11 +46,11 @@ protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
private slots: private slots:
void onChange();
void onSubmit(); void onSubmit();
void onSave(); void onSave();
private: private:
void typeChanged(DBIConnectionType type);
void updateControlsVisibility(); void updateControlsVisibility();
void updateControlsPosition(); void updateControlsPosition();
@ -55,9 +58,10 @@ private:
object_ptr<Ui::PortInput> _portInput; object_ptr<Ui::PortInput> _portInput;
object_ptr<Ui::InputField> _userInput; object_ptr<Ui::InputField> _userInput;
object_ptr<Ui::PasswordInput> _passwordInput; object_ptr<Ui::PasswordInput> _passwordInput;
object_ptr<Ui::Radiobutton> _autoRadio; std::shared_ptr<Ui::RadioenumGroup<DBIConnectionType>> _typeGroup;
object_ptr<Ui::Radiobutton> _httpProxyRadio; object_ptr<Ui::Radioenum<DBIConnectionType>> _autoRadio;
object_ptr<Ui::Radiobutton> _tcpProxyRadio; object_ptr<Ui::Radioenum<DBIConnectionType>> _httpProxyRadio;
object_ptr<Ui::Radioenum<DBIConnectionType>> _tcpProxyRadio;
object_ptr<Ui::Checkbox> _tryIPv6; object_ptr<Ui::Checkbox> _tryIPv6;
}; };

View file

@ -31,9 +31,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
DownloadPathBox::DownloadPathBox(QWidget *parent) DownloadPathBox::DownloadPathBox(QWidget *parent)
: _path(Global::DownloadPath()) : _path(Global::DownloadPath())
, _pathBookmark(Global::DownloadPathBookmark()) , _pathBookmark(Global::DownloadPathBookmark())
, _default(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty(), st::defaultBoxCheckbox) , _group(std::make_shared<Ui::RadioenumGroup<Directory>>(typeFromPath(_path)))
, _temp(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), (_path == qsl("tmp")), st::defaultBoxCheckbox) , _default(this, _group, Directory::Downloads, lang(lng_download_path_default_radio), st::defaultBoxCheckbox)
, _dir(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), (!_path.isEmpty() && _path != qsl("tmp")), st::defaultBoxCheckbox) , _temp(this, _group, Directory::Temp, lang(lng_download_path_temp_radio), st::defaultBoxCheckbox)
, _dir(this, _group, Directory::Custom, lang(lng_download_path_dir_radio), st::defaultBoxCheckbox)
, _pathLink(this, QString(), st::boxLinkButton) { , _pathLink(this, QString(), st::boxLinkButton) {
} }
@ -43,9 +44,7 @@ void DownloadPathBox::prepare() {
setTitle(lang(lng_download_path_header)); setTitle(lang(lng_download_path_header));
connect(_default, SIGNAL(changed()), this, SLOT(onChange())); _group->setChangedCallback([this](Directory value) { radioChanged(value); });
connect(_temp, SIGNAL(changed()), this, SLOT(onChange()));
connect(_dir, SIGNAL(changed()), this, SLOT(onChange()));
connect(_pathLink, SIGNAL(clicked()), this, SLOT(onEditPath())); connect(_pathLink, SIGNAL(clicked()), this, SLOT(onEditPath()));
if (!_path.isEmpty() && _path != qsl("tmp")) { if (!_path.isEmpty() && _path != qsl("tmp")) {
@ -55,10 +54,11 @@ void DownloadPathBox::prepare() {
} }
void DownloadPathBox::updateControlsVisibility() { void DownloadPathBox::updateControlsVisibility() {
_pathLink->setVisible(_dir->checked()); auto custom = (_group->value() == Directory::Custom);
_pathLink->setVisible(custom);
auto newHeight = st::boxOptionListPadding.top() + _default->heightNoMargins() + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins(); auto newHeight = st::boxOptionListPadding.top() + _default->heightNoMargins() + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins();
if (_dir->checked()) { if (custom) {
newHeight += st::downloadPathSkip + _pathLink->height(); newHeight += st::downloadPathSkip + _pathLink->height();
} }
newHeight += st::boxOptionListPadding.bottom(); newHeight += st::boxOptionListPadding.bottom();
@ -78,18 +78,15 @@ void DownloadPathBox::resizeEvent(QResizeEvent *e) {
_pathLink->moveToLeft(inputx, inputy); _pathLink->moveToLeft(inputx, inputy);
} }
void DownloadPathBox::onChange() { void DownloadPathBox::radioChanged(Directory value) {
if (_dir->checked()) { if (value == Directory::Custom) {
if (_path.isEmpty() || _path == qsl("tmp")) { if (_path.isEmpty() || _path == qsl("tmp")) {
(_path.isEmpty() ? _default : _temp)->setChecked(true); _group->setValue(_path.isEmpty() ? Directory::Downloads : Directory::Temp);
onEditPath(); onEditPath();
if (!_path.isEmpty() && _path != qsl("tmp")) {
_dir->setChecked(true);
}
} else { } else {
setPathText(QDir::toNativeSeparators(_path)); setPathText(QDir::toNativeSeparators(_path));
} }
} else if (_temp->checked()) { } else if (value == Directory::Temp) {
_path = qsl("tmp"); _path = qsl("tmp");
} else { } else {
_path = QString(); _path = QString();
@ -110,14 +107,24 @@ void DownloadPathBox::onEditPath() {
_path = result + '/'; _path = result + '/';
_pathBookmark = psDownloadPathBookmark(_path); _pathBookmark = psDownloadPathBookmark(_path);
setPathText(QDir::toNativeSeparators(_path)); setPathText(QDir::toNativeSeparators(_path));
_group->setValue(Directory::Custom);
} }
})); }));
} }
void DownloadPathBox::save() { void DownloadPathBox::save() {
#ifndef OS_WIN_STORE #ifndef OS_WIN_STORE
Global::SetDownloadPath(_default->checked() ? QString() : (_temp->checked() ? qsl("tmp") : _path)); auto value = _group->value();
Global::SetDownloadPathBookmark((_default->checked() || _temp->checked()) ? QByteArray() : _pathBookmark); auto computePath = [this, value] {
if (value == Directory::Custom) {
return _path;
} else if (value == Directory::Temp) {
return qsl("tmp");
}
return QString();
};
Global::SetDownloadPath(computePath());
Global::SetDownloadPathBookmark((value == Directory::Custom) ? _pathBookmark : QByteArray());
Local::writeUserSettings(); Local::writeUserSettings();
Global::RefDownloadPathChanged().notify(); Global::RefDownloadPathChanged().notify();
closeBox(); closeBox();

View file

@ -24,7 +24,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "core/observer.h" #include "core/observer.h"
namespace Ui { namespace Ui {
class Radiobutton; template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
class LinkButton; class LinkButton;
} // namespace Ui } // namespace Ui
@ -40,10 +43,24 @@ protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
private slots: private slots:
void onChange();
void onEditPath(); void onEditPath();
private: private:
enum class Directory {
Downloads,
Temp,
Custom,
};
void radioChanged(Directory value);
Directory typeFromPath(const QString &path) {
if (path.isEmpty()) {
return Directory::Downloads;
} else if (path == qsl("tmp")) {
return Directory::Temp;
}
return Directory::Custom;
}
void save(); void save();
void updateControlsVisibility(); void updateControlsVisibility();
void setPathText(const QString &text); void setPathText(const QString &text);
@ -51,9 +68,10 @@ private:
QString _path; QString _path;
QByteArray _pathBookmark; QByteArray _pathBookmark;
object_ptr<Ui::Radiobutton> _default; std::shared_ptr<Ui::RadioenumGroup<Directory>> _group;
object_ptr<Ui::Radiobutton> _temp; object_ptr<Ui::Radioenum<Directory>> _default;
object_ptr<Ui::Radiobutton> _dir; object_ptr<Ui::Radioenum<Directory>> _temp;
object_ptr<Ui::Radioenum<Directory>> _dir;
object_ptr<Ui::LinkButton> _pathLink; object_ptr<Ui::LinkButton> _pathLink;
}; };

View file

@ -90,7 +90,7 @@ std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxControl
class EditPrivacyBox::OptionWidget : public TWidget { class EditPrivacyBox::OptionWidget : public TWidget {
public: public:
OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadiobuttonGroup> &group, int value, const QString &text, const QString &description); OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadioenumGroup<Option>> &group, Option value, const QString &text, const QString &description);
QMargins getMargins() const override { QMargins getMargins() const override {
return _option->getMargins(); return _option->getMargins();
@ -100,12 +100,12 @@ protected:
int resizeGetHeight(int newWidth) override; int resizeGetHeight(int newWidth) override;
private: private:
object_ptr<Ui::Radiobutton> _option; object_ptr<Ui::Radioenum<Option>> _option;
object_ptr<Ui::FlatLabel> _description; object_ptr<Ui::FlatLabel> _description;
}; };
EditPrivacyBox::OptionWidget::OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadiobuttonGroup> &group, int value, const QString &text, const QString &description) : TWidget(parent) EditPrivacyBox::OptionWidget::OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadioenumGroup<Option>> &group, Option value, const QString &text, const QString &description) : TWidget(parent)
, _option(this, group, value, text, st::defaultBoxCheckbox) , _option(this, group, value, text, st::defaultBoxCheckbox)
, _description(this, description, Ui::FlatLabel::InitType::Simple, st::editPrivacyLabel) { , _description(this, description, Ui::FlatLabel::InitType::Simple, st::editPrivacyLabel) {
} }
@ -178,15 +178,14 @@ int EditPrivacyBox::resizeGetHeight(int newWidth) {
int EditPrivacyBox::countDefaultHeight(int newWidth) { int EditPrivacyBox::countDefaultHeight(int newWidth) {
auto height = 0; auto height = 0;
auto fakeGroup = std::make_shared<Ui::RadiobuttonGroup>(0); auto fakeGroup = std::make_shared<Ui::RadioenumGroup<Option>>(Option::Everyone);
auto optionHeight = [this, newWidth, &fakeGroup](Option option, const QString &label) { auto optionHeight = [this, newWidth, &fakeGroup](Option option, const QString &label) {
auto description = _controller->optionDescription(option); auto description = _controller->optionDescription(option);
if (description.isEmpty()) { if (description.isEmpty()) {
return 0; return 0;
} }
auto value = static_cast<int>(Option::Everyone); auto fake = object_ptr<OptionWidget>(nullptr, fakeGroup, Option::Everyone, label, description);
auto fake = object_ptr<OptionWidget>(nullptr, fakeGroup, value, label, description);
fake->resizeToNaturalWidth(newWidth - st::editPrivacyOptionMargin.left() - st::editPrivacyOptionMargin.right()); fake->resizeToNaturalWidth(newWidth - st::editPrivacyOptionMargin.left() - st::editPrivacyOptionMargin.right());
return st::editPrivacyOptionMargin.top() + fake->heightNoMargins() + st::editPrivacyOptionMargin.bottom(); return st::editPrivacyOptionMargin.top() + fake->heightNoMargins() + st::editPrivacyOptionMargin.bottom();
}; };
@ -296,20 +295,19 @@ void EditPrivacyBox::createOption(Option option, object_ptr<OptionWidget> &widge
auto description = _controller->optionDescription(option); auto description = _controller->optionDescription(option);
auto selected = (_option == option); auto selected = (_option == option);
if (!description.isEmpty() || selected) { if (!description.isEmpty() || selected) {
auto value = static_cast<int>(option); widget.create(this, _optionGroup, option, label, description);
widget.create(this, _optionGroup, value, label, description);
} }
} }
void EditPrivacyBox::createWidgets() { void EditPrivacyBox::createWidgets() {
_loading.destroy(); _loading.destroy();
_optionGroup = std::make_shared<Ui::RadiobuttonGroup>(static_cast<int>(_option)); _optionGroup = std::make_shared<Ui::RadioenumGroup<Option>>(_option);
createOption(Option::Everyone, _everyone, lang(lng_edit_privacy_everyone)); createOption(Option::Everyone, _everyone, lang(lng_edit_privacy_everyone));
createOption(Option::Contacts, _contacts, lang(lng_edit_privacy_contacts)); createOption(Option::Contacts, _contacts, lang(lng_edit_privacy_contacts));
createOption(Option::Nobody, _nobody, lang(lng_edit_privacy_nobody)); createOption(Option::Nobody, _nobody, lang(lng_edit_privacy_nobody));
_optionGroup->setChangedCallback([this](int value) { _optionGroup->setChangedCallback([this](Option value) {
_option = static_cast<Option>(value); _option = value;
_alwaysLink->toggleAnimated(showExceptionLink(Exception::Always)); _alwaysLink->toggleAnimated(showExceptionLink(Exception::Always));
_neverLink->toggleAnimated(showExceptionLink(Exception::Never)); _neverLink->toggleAnimated(showExceptionLink(Exception::Never));
}); });

View file

@ -25,7 +25,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace Ui { namespace Ui {
class FlatLabel; class FlatLabel;
class LinkButton; class LinkButton;
class RadiobuttonGroup; template <typename Enum>
class RadioenumGroup;
template <typename Widget> template <typename Widget>
class WidgetSlideWrap; class WidgetSlideWrap;
} // namespace Ui } // namespace Ui
@ -104,7 +105,7 @@ private:
std::unique_ptr<Controller> _controller; std::unique_ptr<Controller> _controller;
Option _option = Option::Everyone; Option _option = Option::Everyone;
std::shared_ptr<Ui::RadiobuttonGroup> _optionGroup; std::shared_ptr<Ui::RadioenumGroup<Option>> _optionGroup;
object_ptr<Ui::FlatLabel> _loading; object_ptr<Ui::FlatLabel> _loading;
object_ptr<OptionWidget> _everyone = { nullptr }; object_ptr<OptionWidget> _everyone = { nullptr };
object_ptr<OptionWidget> _contacts = { nullptr }; object_ptr<OptionWidget> _contacts = { nullptr };

View file

@ -30,11 +30,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwindow.h" #include "mainwindow.h"
ReportBox::ReportBox(QWidget*, PeerData *peer) : _peer(peer) ReportBox::ReportBox(QWidget*, PeerData *peer) : _peer(peer)
, _reasonGroup(std::make_shared<Ui::RadiobuttonGroup>(ReasonSpam)) , _reasonGroup(std::make_shared<Ui::RadioenumGroup<Reason>>(Reason::Spam))
, _reasonSpam(this, _reasonGroup, ReasonSpam, lang(lng_report_reason_spam), st::defaultBoxCheckbox) , _reasonSpam(this, _reasonGroup, Reason::Spam, lang(lng_report_reason_spam), st::defaultBoxCheckbox)
, _reasonViolence(this, _reasonGroup, ReasonViolence, lang(lng_report_reason_violence), st::defaultBoxCheckbox) , _reasonViolence(this, _reasonGroup, Reason::Violence, lang(lng_report_reason_violence), st::defaultBoxCheckbox)
, _reasonPornography(this, _reasonGroup, ReasonPornography, lang(lng_report_reason_pornography), st::defaultBoxCheckbox) , _reasonPornography(this, _reasonGroup, Reason::Pornography, lang(lng_report_reason_pornography), st::defaultBoxCheckbox)
, _reasonOther(this, _reasonGroup, ReasonOther, lang(lng_report_reason_other), st::defaultBoxCheckbox) { , _reasonOther(this, _reasonGroup, Reason::Other, lang(lng_report_reason_other), st::defaultBoxCheckbox) {
} }
void ReportBox::prepare() { void ReportBox::prepare() {
@ -43,7 +43,7 @@ void ReportBox::prepare() {
addButton(lang(lng_report_button), [this] { onReport(); }); addButton(lang(lng_report_button), [this] { onReport(); });
addButton(lang(lng_cancel), [this] { closeBox(); }); addButton(lang(lng_cancel), [this] { closeBox(); });
_reasonGroup->setChangedCallback([this](int value) { reasonChanged(value); }); _reasonGroup->setChangedCallback([this](Reason value) { reasonChanged(value); });
updateMaxHeight(); updateMaxHeight();
} }
@ -61,8 +61,8 @@ void ReportBox::resizeEvent(QResizeEvent *e) {
} }
} }
void ReportBox::reasonChanged(int reason) { void ReportBox::reasonChanged(Reason reason) {
if (reason == ReasonOther) { if (reason == Reason::Other) {
if (!_reasonOtherText) { if (!_reasonOtherText) {
_reasonOtherText.create(this, st::profileReportReasonOther, lang(lng_report_reason_description)); _reasonOtherText.create(this, st::profileReportReasonOther, lang(lng_report_reason_description));
_reasonOtherText->show(); _reasonOtherText->show();
@ -105,10 +105,10 @@ void ReportBox::onReport() {
auto getReason = [this]() { auto getReason = [this]() {
switch (_reasonGroup->value()) { switch (_reasonGroup->value()) {
case ReasonSpam: return MTP_inputReportReasonSpam(); case Reason::Spam: return MTP_inputReportReasonSpam();
case ReasonViolence: return MTP_inputReportReasonViolence(); case Reason::Violence: return MTP_inputReportReasonViolence();
case ReasonPornography: return MTP_inputReportReasonPornography(); case Reason::Pornography: return MTP_inputReportReasonPornography();
case ReasonOther: return MTP_inputReportReasonOther(MTP_string(_reasonOtherText->getLastText())); case Reason::Other: return MTP_inputReportReasonOther(MTP_string(_reasonOtherText->getLastText()));
} }
Unexpected("Bad reason group value."); Unexpected("Bad reason group value.");
}; };

View file

@ -23,8 +23,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/abstractbox.h" #include "boxes/abstractbox.h"
namespace Ui { namespace Ui {
class RadiobuttonGroup; template <typename Enum>
class Radiobutton; class RadioenumGroup;
template <typename Enum>
class Radioenum;
class InputArea; class InputArea;
} // namespace Ui } // namespace Ui
@ -48,7 +50,13 @@ protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
private: private:
void reasonChanged(int reason); enum class Reason {
Spam,
Violence,
Pornography,
Other,
};
void reasonChanged(Reason reason);
void updateMaxHeight(); void updateMaxHeight();
void reportDone(const MTPBool &result); void reportDone(const MTPBool &result);
@ -56,19 +64,13 @@ private:
PeerData *_peer; PeerData *_peer;
std::shared_ptr<Ui::RadiobuttonGroup> _reasonGroup; std::shared_ptr<Ui::RadioenumGroup<Reason>> _reasonGroup;
object_ptr<Ui::Radiobutton> _reasonSpam; object_ptr<Ui::Radioenum<Reason>> _reasonSpam;
object_ptr<Ui::Radiobutton> _reasonViolence; object_ptr<Ui::Radioenum<Reason>> _reasonViolence;
object_ptr<Ui::Radiobutton> _reasonPornography; object_ptr<Ui::Radioenum<Reason>> _reasonPornography;
object_ptr<Ui::Radiobutton> _reasonOther; object_ptr<Ui::Radioenum<Reason>> _reasonOther;
object_ptr<Ui::InputArea> _reasonOtherText = { nullptr }; object_ptr<Ui::InputArea> _reasonOtherText = { nullptr };
enum Reason {
ReasonSpam,
ReasonViolence,
ReasonPornography,
ReasonOther,
};
mtpRequestId _requestId = 0; mtpRequestId _requestId = 0;
}; };

View file

@ -90,12 +90,8 @@ void BlockWidget::createChildRow(object_ptr<Ui::Checkbox> &child, style::margins
connect(child, SIGNAL(changed()), this, slot); connect(child, SIGNAL(changed()), this, slot);
} }
void BlockWidget::createChildRow(object_ptr<Ui::Radiobutton> &child, style::margins &margin, const std::shared_ptr<Ui::RadiobuttonGroup> &group, int value, const QString &text) {
child.create(this, group, value, text, st::defaultBoxCheckbox);
}
void BlockWidget::createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st) { void BlockWidget::createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st) {
child .create(this, text, st); child.create(this, text, st);
connect(child, SIGNAL(clicked()), this, slot); connect(child, SIGNAL(clicked()), this, slot);
} }

View file

@ -28,6 +28,10 @@ class Checkbox;
class RadiobuttonGroup; class RadiobuttonGroup;
class Radiobutton; class Radiobutton;
class LinkButton; class LinkButton;
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Widget> template <typename Widget>
class WidgetSlideWrap; class WidgetSlideWrap;
} // namespace Ui } // namespace Ui
@ -88,27 +92,35 @@ private:
margin.setBottom(margin.bottom() - padding.bottom()); margin.setBottom(margin.bottom() - padding.bottom());
} }
void createChildRow(object_ptr<Ui::Checkbox> &child, style::margins &margin, const QString &text, const char *slot, bool checked); void createChildRow(object_ptr<Ui::Checkbox> &child, style::margins &margin, const QString &text, const char *slot, bool checked);
void createChildRow(object_ptr<Ui::Radiobutton> &child, style::margins &margin, const Ui::RadiobuttonGroup &group, int value, const QString &text);
void createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st = st::boxLinkButton); void createChildRow(object_ptr<Ui::LinkButton> &child, style::margins &margin, const QString &text, const char *slot, const style::LinkButton &st = st::boxLinkButton);
template <typename Enum>
void createChildRow(object_ptr<Ui::Radioenum<Enum>> &child, style::margins &margin, const std::shared_ptr<Ui::RadioenumGroup<Enum>> &group, Enum value, const QString &text) {
child.create(this, group, value, text, st::defaultBoxCheckbox);
}
void addCreatedRow(TWidget *child, const style::margins &margin); void addCreatedRow(TWidget *child, const style::margins &margin);
void rowHeightUpdated(); void rowHeightUpdated();
template <typename Widget> template <typename Widget>
struct IsWidgetSlideWrap { struct IsWidgetSlideWrap : std::false_type {
static constexpr bool value = false;
}; };
template <typename Widget> template <typename Widget>
struct IsWidgetSlideWrap<Ui::WidgetSlideWrap<Widget>> { struct IsWidgetSlideWrap<Ui::WidgetSlideWrap<Widget>> : std::true_type {
static constexpr bool value = true; };
template <typename Widget>
struct IsRadioenum : std::false_type {
};
template <typename Enum>
struct IsRadioenum<Ui::Radioenum<Enum>> : std::true_type {
}; };
template <typename Widget> template <typename Widget>
using NotImplementedYet = std::enable_if_t< using NotImplementedYet = std::enable_if_t<
!IsWidgetSlideWrap<Widget>::value && !IsWidgetSlideWrap<Widget>::value &&
!std::is_same<Widget, Ui::Checkbox>::value && !IsRadioenum<Widget>::value &&
!std::is_same<Widget, Ui::Radiobutton>::value && !std::is_same<Ui::Checkbox, Widget>::value &&
!std::is_same<Widget, Ui::LinkButton>::value>; !std::is_same<Ui::LinkButton, Widget>::value>;
template <typename Widget, typename... Args, typename = NotImplementedYet<Widget>> template <typename Widget, typename... Args, typename = NotImplementedYet<Widget>>
void createChildRow(object_ptr<Widget> &child, style::margins &margin, Args&&... args) { void createChildRow(object_ptr<Widget> &child, style::margins &margin, Args&&... args) {

View file

@ -180,10 +180,10 @@ void ChatSettingsWidget::createControls() {
} }
#endif // OS_WIN_STORE #endif // OS_WIN_STORE
auto group = std::make_shared<Ui::RadiobuttonGroup>(cCtrlEnter() ? 1 : 0); auto group = std::make_shared<Ui::RadioenumGroup<SendByType>>(cCtrlEnter() ? SendByType::CtrlEnter : SendByType::Enter);
addChildRow(_sendByEnter, marginSmall, group, 0, lang(lng_settings_send_enter)); addChildRow(_sendByEnter, marginSmall, group, SendByType::Enter, lang(lng_settings_send_enter));
addChildRow(_sendByCtrlEnter, marginSkip, group, 1, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter), SLOT(onSendByCtrlEnter()), cCtrlEnter()); addChildRow(_sendByCtrlEnter, marginSkip, group, SendByType::CtrlEnter, lang((cPlatform() == dbipMac || cPlatform() == dbipMacOld) ? lng_settings_send_cmdenter : lng_settings_send_ctrlenter));
group->setChangedCallback([this](int value) { group->setChangedCallback([this](SendByType value) {
sendByChanged(value); sendByChanged(value);
}); });
@ -210,8 +210,8 @@ void ChatSettingsWidget::onDontAskDownloadPath() {
#endif // OS_WIN_STORE #endif // OS_WIN_STORE
} }
void ChatSettingsWidget::sendByChanged(int value) { void ChatSettingsWidget::sendByChanged(SendByType value) {
cSetCtrlEnter(value == 1); cSetCtrlEnter(value == SendByType::CtrlEnter);
if (App::main()) App::main()->ctrlEnterSubmitUpdated(); if (App::main()) App::main()->ctrlEnterSubmitUpdated();
Local::writeUserSettings(); Local::writeUserSettings();
} }

View file

@ -102,7 +102,11 @@ private slots:
void onManageStickerSets(); void onManageStickerSets();
private: private:
void sendByChanged(int value); enum class SendByType {
Enter,
CtrlEnter,
};
void sendByChanged(SendByType value);
void createControls(); void createControls();
object_ptr<Ui::Checkbox> _replaceEmoji = { nullptr }; object_ptr<Ui::Checkbox> _replaceEmoji = { nullptr };
@ -113,8 +117,8 @@ private:
object_ptr<Ui::WidgetSlideWrap<DownloadPathState>> _downloadPath = { nullptr }; object_ptr<Ui::WidgetSlideWrap<DownloadPathState>> _downloadPath = { nullptr };
#endif // OS_WIN_STORE #endif // OS_WIN_STORE
object_ptr<Ui::Radiobutton> _sendByEnter = { nullptr }; object_ptr<Ui::Radioenum<SendByType>> _sendByEnter = { nullptr };
object_ptr<Ui::Radiobutton> _sendByCtrlEnter = { nullptr }; object_ptr<Ui::Radioenum<SendByType>> _sendByCtrlEnter = { nullptr };
object_ptr<Ui::LinkButton> _automaticMediaDownloadSettings = { nullptr }; object_ptr<Ui::LinkButton> _automaticMediaDownloadSettings = { nullptr };
object_ptr<Ui::LinkButton> _manageStickerSets = { nullptr }; object_ptr<Ui::LinkButton> _manageStickerSets = { nullptr };

View file

@ -91,6 +91,8 @@ public:
} }
void setValue(int value); void setValue(int value);
private:
friend class Radiobutton;
void registerButton(Radiobutton *button) { void registerButton(Radiobutton *button) {
if (!base::contains(_buttons, button)) { if (!base::contains(_buttons, button)) {
_buttons.push_back(button); _buttons.push_back(button);
@ -100,11 +102,6 @@ public:
_buttons.erase(std::remove(_buttons.begin(), _buttons.end(), button), _buttons.end()); _buttons.erase(std::remove(_buttons.begin(), _buttons.end(), button), _buttons.end());
} }
private:
friend class Radiobutton;
void registerButton(Radiobutton *button);
void unregisterButton(Radiobutton *button);
int _value = 0; int _value = 0;
bool _hasValue = false; bool _hasValue = false;
base::lambda<void(int value)> _changedCallback; base::lambda<void(int value)> _changedCallback;
@ -116,9 +113,6 @@ class Radiobutton : public RippleButton {
public: public:
Radiobutton(QWidget *parent, const std::shared_ptr<RadiobuttonGroup> &group, int value, const QString &text, const style::Checkbox &st = st::defaultCheckbox); Radiobutton(QWidget *parent, const std::shared_ptr<RadiobuttonGroup> &group, int value, const QString &text, const style::Checkbox &st = st::defaultCheckbox);
RadiobuttonGroup *group() const {
return _group.get();
}
QMargins getMargins() const override { QMargins getMargins() const override {
return _st.margin; return _st.margin;
} }
@ -152,4 +146,48 @@ private:
}; };
template <typename Enum>
class Radioenum;
template <typename Enum>
class RadioenumGroup {
public:
RadioenumGroup() = default;
RadioenumGroup(Enum value) : _group(static_cast<int>(value)) {
}
template <typename Callback>
void setChangedCallback(Callback &&callback) {
_group.setChangedCallback([callback](int value) {
callback(static_cast<Enum>(value));
});
}
bool hasValue() const {
return _group.hasValue();
}
Enum value() const {
return static_cast<Enum>(_group.value());
}
void setValue(Enum value) {
_group.setValue(static_cast<int>(value));
}
private:
template <typename OtherEnum>
friend class Radioenum;
RadiobuttonGroup _group;
};
template <typename Enum>
class Radioenum : public Radiobutton {
public:
Radioenum(QWidget *parent, const std::shared_ptr<RadioenumGroup<Enum>> &group, Enum value, const QString &text, const style::Checkbox &st = st::defaultCheckbox)
: Radiobutton(parent, std::shared_ptr<RadiobuttonGroup>(group, &group->_group), static_cast<int>(value), text, st) {
}
};
} // namespace Ui } // namespace Ui