mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-30 23:38:25 +00:00
Refactor calls settings panel.
This commit is contained in:
parent
8711830f66
commit
65430d92ea
Telegram/SourceFiles
boxes
platform
settings
ui/widgets
@ -13,27 +13,48 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
SingleChoiceBox::SingleChoiceBox(
|
||||
QWidget*,
|
||||
LangKey title,
|
||||
const std::vector<QString> &optionTexts,
|
||||
int initialSelection,
|
||||
Fn<void(int)> callback)
|
||||
: _title(title)
|
||||
, _optionTexts(optionTexts)
|
||||
, _initialSelection(initialSelection)
|
||||
, _callback(callback) {
|
||||
}
|
||||
|
||||
void SingleChoiceBox::prepare() {
|
||||
setTitle(langFactory(_title));
|
||||
|
||||
addButton(langFactory(lng_box_ok), [this] { closeBox(); });
|
||||
addButton(langFactory(lng_box_ok), [=] { closeBox(); });
|
||||
|
||||
auto group = std::make_shared<Ui::RadiobuttonGroup>(_initialSelection);
|
||||
auto y = st::boxOptionListPadding.top() + st::autolockButton.margin.top();
|
||||
auto count = int(_optionTexts.size());
|
||||
_options.reserve(count);
|
||||
const auto group = std::make_shared<Ui::RadiobuttonGroup>(_initialSelection);
|
||||
auto y = st::boxOptionListPadding.top()
|
||||
+ st::autolockButton.margin.top();
|
||||
_options.reserve(_optionTexts.size());
|
||||
auto i = 0;
|
||||
for (const auto &text : _optionTexts) {
|
||||
_options.emplace_back(this, group, i, text, st::autolockButton);
|
||||
_options.back()->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), y);
|
||||
_options.back()->moveToLeft(
|
||||
st::boxPadding.left() + st::boxOptionListPadding.left(),
|
||||
y);
|
||||
y += _options.back()->heightNoMargins() + st::boxOptionListSkip;
|
||||
i++;
|
||||
}
|
||||
group->setChangedCallback([this](int value) {
|
||||
group->setChangedCallback([=](int value) {
|
||||
const auto weak = make_weak(this);
|
||||
_callback(value);
|
||||
closeBox();
|
||||
if (weak) {
|
||||
closeBox();
|
||||
}
|
||||
});
|
||||
|
||||
setDimensions(st::autolockWidth, st::boxOptionListPadding.top() + count * _options.back()->heightNoMargins() + (count - 1) * st::boxOptionListSkip + st::boxOptionListPadding.bottom() + st::boxPadding.bottom());
|
||||
const auto height = y
|
||||
- st::boxOptionListSkip
|
||||
+ st::boxOptionListPadding.bottom()
|
||||
+ st::boxPadding.bottom();
|
||||
setDimensions(st::autolockWidth, height);
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,12 @@ class Radiobutton;
|
||||
|
||||
class SingleChoiceBox : public BoxContent {
|
||||
public:
|
||||
SingleChoiceBox(QWidget*, LangKey title, std::vector<QString> optionTexts, int initialSelection, Fn<void(int)> callback) : _title(title), _optionTexts(optionTexts), _initialSelection(initialSelection), _callback(callback) {
|
||||
}
|
||||
SingleChoiceBox(
|
||||
QWidget*,
|
||||
LangKey title,
|
||||
const std::vector<QString> &optionTexts,
|
||||
int initialSelection,
|
||||
Fn<void(int)> callback);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
|
@ -491,24 +491,23 @@ void OpenSystemSettingsForPermission(PermissionType type) {
|
||||
|
||||
bool OpenSystemSettings(SystemSettingsType type) {
|
||||
if (type == SystemSettingsType::Audio) {
|
||||
bool succeeded = false;
|
||||
auto options = std::vector<QString>();
|
||||
const auto add = [&](const char *option) {
|
||||
options.emplace_back(option);
|
||||
};
|
||||
if (DesktopEnvironment::IsUnity()) {
|
||||
succeeded |= QProcess::startDetached(qsl("unity-control-center sound"));
|
||||
add("unity-control-center sound");
|
||||
} else if (DesktopEnvironment::IsKDE()) {
|
||||
succeeded |= QProcess::startDetached(qsl("kcmshell5 kcm_pulseaudio"));
|
||||
if (!succeeded) {
|
||||
succeeded |= QProcess::startDetached(qsl("kcmshell4 phonon"));
|
||||
}
|
||||
add("kcmshell5 kcm_pulseaudio");
|
||||
add("kcmshell4 phonon");
|
||||
} else if (DesktopEnvironment::IsGnome()) {
|
||||
succeeded |= QProcess::startDetached(qsl("gnome-control-center sound"));
|
||||
add("gnome-control-center sound");
|
||||
}
|
||||
if (!succeeded) {
|
||||
succeeded |= QProcess::startDetached(qsl("pavucontrol"));
|
||||
}
|
||||
if (!succeeded) {
|
||||
succeeded |= QProcess::startDetached(qsl("alsamixergui"));
|
||||
}
|
||||
return succeeded;
|
||||
add("pavucontrol");
|
||||
add("alsamixergui");
|
||||
return ranges::find_if(options, [](const QString &command) {
|
||||
return QProcess::startDetached(command);
|
||||
}) != end(options);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -334,9 +334,9 @@ void OpenSystemSettingsForPermission(PermissionType type) {
|
||||
|
||||
bool OpenSystemSettings(SystemSettingsType type) {
|
||||
switch (type) {
|
||||
case SystemSettingsType::Audio:
|
||||
[[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Sound.prefPane"];
|
||||
break;
|
||||
case SystemSettingsType::Audio:
|
||||
[[NSWorkspace sharedWorkspace] openFile:@"/System/Library/PreferencePanes/Sound.prefPane"];
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -652,14 +652,24 @@ void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCal
|
||||
}
|
||||
|
||||
void OpenSystemSettingsForPermission(PermissionType type) {
|
||||
if (type==PermissionType::Microphone) {
|
||||
ShellExecute(NULL, L"open", L"ms-settings:privacy-microphone", NULL, NULL, SW_SHOWDEFAULT);
|
||||
if (type == PermissionType::Microphone) {
|
||||
crl::on_main([] {
|
||||
ShellExecute(
|
||||
nullptr,
|
||||
L"open",
|
||||
L"ms-settings:privacy-microphone",
|
||||
nullptr,
|
||||
nullptr,
|
||||
SW_SHOWDEFAULT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenSystemSettings(SystemSettingsType type) {
|
||||
if (type == SystemSettingsType::Audio) {
|
||||
WinExec("control.exe mmsys.cpl", SW_SHOW);
|
||||
crl::on_main([] {
|
||||
WinExec("control.exe mmsys.cpl", SW_SHOW);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ Calls::Calls(QWidget *parent, UserData *self)
|
||||
setupContent();
|
||||
}
|
||||
|
||||
Calls::~Calls(){
|
||||
Calls::~Calls() {
|
||||
if (_needWriteSettings) {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void Calls::sectionSaveChanges(FnMut<void()> done){
|
||||
void Calls::sectionSaveChanges(FnMut<void()> done) {
|
||||
if (_micTester) {
|
||||
_micTester.reset();
|
||||
}
|
||||
@ -57,181 +57,219 @@ void Calls::sectionSaveChanges(FnMut<void()> done){
|
||||
}
|
||||
|
||||
void Calls::setupContent() {
|
||||
using namespace tgvoip;
|
||||
|
||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||
const auto getId = [](const auto &device) {
|
||||
return QString::fromStdString(device.id);
|
||||
};
|
||||
const auto getName = [](const auto &device) {
|
||||
return QString::fromStdString(device.displayName);
|
||||
};
|
||||
|
||||
QString currentOutputName;
|
||||
if (Global::CallOutputDeviceID() == qsl("default")) {
|
||||
currentOutputName = lang(lng_settings_call_device_default);
|
||||
} else {
|
||||
std::vector<tgvoip::AudioOutputDevice> outputDevices = tgvoip::VoIPController::EnumerateAudioOutputs();
|
||||
currentOutputName=Global::CallOutputDeviceID();
|
||||
for (auto &dev : outputDevices) {
|
||||
if (QString::fromUtf8(dev.id.c_str()) == Global::CallOutputDeviceID()) {
|
||||
currentOutputName = QString::fromUtf8(dev.displayName.c_str());
|
||||
break;
|
||||
}
|
||||
const auto currentOutputName = [&] {
|
||||
if (Global::CallOutputDeviceID() == qsl("default")) {
|
||||
return lang(lng_settings_call_device_default);
|
||||
}
|
||||
}
|
||||
const auto &list = VoIPController::EnumerateAudioOutputs();
|
||||
const auto i = ranges::find(
|
||||
list,
|
||||
Global::CallOutputDeviceID(),
|
||||
getId);
|
||||
return (i != end(list))
|
||||
? getName(*i)
|
||||
: Global::CallOutputDeviceID();
|
||||
}();
|
||||
|
||||
QString currentInputName;
|
||||
if (Global::CallInputDeviceID() == qsl("default")) {
|
||||
currentInputName = lang(lng_settings_call_device_default);
|
||||
} else {
|
||||
std::vector<tgvoip::AudioInputDevice> inputDevices = tgvoip::VoIPController::EnumerateAudioInputs();
|
||||
currentInputName = Global::CallInputDeviceID();
|
||||
for (auto &dev : inputDevices) {
|
||||
if (QString::fromUtf8(dev.id.c_str()) == Global::CallInputDeviceID()) {
|
||||
currentInputName = QString::fromUtf8(dev.displayName.c_str());
|
||||
break;
|
||||
}
|
||||
const auto currentInputName = [&] {
|
||||
if (Global::CallInputDeviceID() == qsl("default")) {
|
||||
return lang(lng_settings_call_device_default);
|
||||
}
|
||||
}
|
||||
const auto &list = VoIPController::EnumerateAudioInputs();
|
||||
const auto i = ranges::find(
|
||||
list,
|
||||
Global::CallInputDeviceID(),
|
||||
getId);
|
||||
return (i != end(list))
|
||||
? getName(*i)
|
||||
: Global::CallInputDeviceID();
|
||||
}();
|
||||
|
||||
AddSkip(content);
|
||||
AddSubsectionTitle(content, lng_settings_call_section_output);
|
||||
const auto outputButton = AddButtonWithLabel(
|
||||
AddButtonWithLabel(
|
||||
content,
|
||||
lng_settings_call_output_device,
|
||||
rpl::single(currentOutputName) | rpl::then(_outputNameStream.events()),
|
||||
st::settingsButton);
|
||||
outputButton->addClickHandler([this] {
|
||||
int selectedOption = 0;
|
||||
std::vector<tgvoip::AudioOutputDevice> devices = tgvoip::VoIPController::EnumerateAudioOutputs();
|
||||
std::vector<QString> options;
|
||||
options.push_back(lang(lng_settings_call_device_default));
|
||||
int i = 1;
|
||||
for (auto &device : devices) {
|
||||
QString displayName = QString::fromUtf8(device.displayName.c_str());
|
||||
options.push_back(displayName);
|
||||
if (QString::fromUtf8(device.id.c_str()) == Global::CallOutputDeviceID()) {
|
||||
selectedOption = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
const auto save = crl::guard(this, [=](int selectedOption) {
|
||||
QString name = options[selectedOption];
|
||||
_outputNameStream.fire(std::move(name));
|
||||
std::string selectedDeviceID;
|
||||
if (selectedOption == 0) {
|
||||
selectedDeviceID = "default";
|
||||
} else {
|
||||
selectedDeviceID = devices[selectedOption-1].id;
|
||||
}
|
||||
Global::SetCallOutputDeviceID(QString::fromStdString(selectedDeviceID));
|
||||
rpl::single(
|
||||
currentOutputName
|
||||
) | rpl::then(
|
||||
_outputNameStream.events()
|
||||
),
|
||||
st::settingsButton
|
||||
)->addClickHandler([=] {
|
||||
const auto &devices = VoIPController::EnumerateAudioOutputs();
|
||||
const auto options = ranges::view::concat(
|
||||
ranges::view::single(lang(lng_settings_call_device_default)),
|
||||
devices | ranges::view::transform(getName)
|
||||
) | ranges::to_vector;
|
||||
const auto i = ranges::find(
|
||||
devices,
|
||||
Global::CallOutputDeviceID(),
|
||||
getId);
|
||||
const auto currentOption = (i != end(devices))
|
||||
? int(i - begin(devices) + 1)
|
||||
: 0;
|
||||
const auto save = crl::guard(this, [=](int option) {
|
||||
_outputNameStream.fire_copy(options[option]);
|
||||
const auto deviceId = option
|
||||
? devices[option - 1].id
|
||||
: "default";
|
||||
Global::SetCallOutputDeviceID(QString::fromStdString(deviceId));
|
||||
Local::writeUserSettings();
|
||||
|
||||
::Calls::Call *currentCall = ::Calls::Current().currentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setCurrentAudioDevice(false, selectedDeviceID);
|
||||
if (const auto call = ::Calls::Current().currentCall()) {
|
||||
call->setCurrentAudioDevice(false, deviceId);
|
||||
}
|
||||
});
|
||||
Ui::show(Box<SingleChoiceBox>(lng_settings_call_output_device, options, selectedOption, save));
|
||||
Ui::show(Box<SingleChoiceBox>(
|
||||
lng_settings_call_output_device,
|
||||
options,
|
||||
currentOption,
|
||||
save));
|
||||
});
|
||||
|
||||
const auto outputLabel = content->add(object_ptr<Ui::LabelSimple>(content, st::settingsAudioVolumeLabel), st::settingsAudioVolumeLabelPadding);
|
||||
const auto outputSlider = content->add(object_ptr<Ui::MediaSlider>(content, st::settingsAudioVolumeSlider), st::settingsAudioVolumeSliderPadding);
|
||||
auto updateOutputLabel = [outputLabel](int value){
|
||||
QString percent = QString::number(value);
|
||||
outputLabel->setText(lng_settings_call_output_volume(lt_percent, percent));
|
||||
const auto outputLabel = content->add(
|
||||
object_ptr<Ui::LabelSimple>(
|
||||
content,
|
||||
st::settingsAudioVolumeLabel),
|
||||
st::settingsAudioVolumeLabelPadding);
|
||||
const auto outputSlider = content->add(
|
||||
object_ptr<Ui::MediaSlider>(
|
||||
content,
|
||||
st::settingsAudioVolumeSlider),
|
||||
st::settingsAudioVolumeSliderPadding);
|
||||
const auto updateOutputLabel = [=](int value) {
|
||||
const auto percent = QString::number(value);
|
||||
outputLabel->setText(
|
||||
lng_settings_call_output_volume(lt_percent, percent));
|
||||
};
|
||||
const auto updateOutputVolume = [=](int value) {
|
||||
_needWriteSettings = true;
|
||||
updateOutputLabel(value);
|
||||
Global::SetCallOutputVolume(value);
|
||||
if (const auto call = ::Calls::Current().currentCall()) {
|
||||
call->setAudioVolume(false, value / 100.0f);
|
||||
}
|
||||
};
|
||||
outputSlider->resize(st::settingsAudioVolumeSlider.seekSize);
|
||||
outputSlider->setPseudoDiscrete(
|
||||
201,
|
||||
[](int val){
|
||||
return val;
|
||||
},
|
||||
[](int val) { return val; },
|
||||
Global::CallOutputVolume(),
|
||||
[updateOutputLabel, this](int value) {
|
||||
_needWriteSettings = true;
|
||||
updateOutputLabel(value);
|
||||
Global::SetCallOutputVolume(value);
|
||||
::Calls::Call* currentCall = ::Calls::Current().currentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setAudioVolume(false, value/100.0f);
|
||||
}
|
||||
});
|
||||
updateOutputVolume);
|
||||
updateOutputLabel(Global::CallOutputVolume());
|
||||
|
||||
AddSkip(content);
|
||||
AddDivider(content);
|
||||
AddSkip(content);
|
||||
AddSubsectionTitle(content, lng_settings_call_section_input);
|
||||
const auto inputButton = AddButtonWithLabel(
|
||||
AddButtonWithLabel(
|
||||
content,
|
||||
lng_settings_call_input_device,
|
||||
rpl::single(currentInputName) | rpl::then(_inputNameStream.events()),
|
||||
st::settingsButton);
|
||||
inputButton->addClickHandler([this] {
|
||||
int selectedOption = 0;
|
||||
std::vector<tgvoip::AudioInputDevice> devices = tgvoip::VoIPController::EnumerateAudioInputs();
|
||||
std::vector<QString> options;
|
||||
options.push_back(lang(lng_settings_call_device_default));
|
||||
int i = 1;
|
||||
for (auto &device : devices) {
|
||||
QString displayName = QString::fromUtf8(device.displayName.c_str());
|
||||
options.push_back(displayName);
|
||||
if(QString::fromUtf8(device.id.c_str()) == Global::CallInputDeviceID())
|
||||
selectedOption = i;
|
||||
i++;
|
||||
}
|
||||
const auto save = crl::guard(this, [=](int selectedOption) {
|
||||
QString name=options[selectedOption];
|
||||
_inputNameStream.fire(std::move(name));
|
||||
std::string selectedDeviceID;
|
||||
if (selectedOption == 0) {
|
||||
selectedDeviceID = "default";
|
||||
} else {
|
||||
selectedDeviceID = devices[selectedOption - 1].id;
|
||||
}
|
||||
Global::SetCallInputDeviceID(QString::fromUtf8(selectedDeviceID.c_str()));
|
||||
rpl::single(
|
||||
currentInputName
|
||||
) | rpl::then(
|
||||
_inputNameStream.events()
|
||||
),
|
||||
st::settingsButton
|
||||
)->addClickHandler([=] {
|
||||
const auto &devices = VoIPController::EnumerateAudioInputs();
|
||||
const auto options = ranges::view::concat(
|
||||
ranges::view::single(lang(lng_settings_call_device_default)),
|
||||
devices | ranges::view::transform(getName)
|
||||
) | ranges::to_vector;
|
||||
const auto i = ranges::find(
|
||||
devices,
|
||||
Global::CallInputDeviceID(),
|
||||
getId);
|
||||
const auto currentOption = (i != end(devices))
|
||||
? int(i - begin(devices) + 1)
|
||||
: 0;
|
||||
const auto save = crl::guard(this, [=](int option) {
|
||||
_inputNameStream.fire_copy(options[option]);
|
||||
const auto deviceId = option
|
||||
? devices[option - 1].id
|
||||
: "default";
|
||||
Global::SetCallInputDeviceID(QString::fromStdString(deviceId));
|
||||
Local::writeUserSettings();
|
||||
if (_micTester) {
|
||||
stopTestingMicrophone();
|
||||
}
|
||||
::Calls::Call *currentCall = ::Calls::Current().currentCall();
|
||||
if(currentCall){
|
||||
currentCall->setCurrentAudioDevice(true, selectedDeviceID);
|
||||
if (const auto call = ::Calls::Current().currentCall()) {
|
||||
call->setCurrentAudioDevice(true, deviceId);
|
||||
}
|
||||
});
|
||||
Ui::show(Box<SingleChoiceBox>(lng_settings_call_input_device, options, selectedOption, save));
|
||||
Ui::show(Box<SingleChoiceBox>(
|
||||
lng_settings_call_input_device,
|
||||
options,
|
||||
currentOption,
|
||||
save));
|
||||
});
|
||||
|
||||
const auto inputLabel = content->add(object_ptr<Ui::LabelSimple>(content, st::settingsAudioVolumeLabel), st::settingsAudioVolumeLabelPadding);
|
||||
const auto inputSlider = content->add(object_ptr<Ui::MediaSlider>(content, st::settingsAudioVolumeSlider), st::settingsAudioVolumeSliderPadding);
|
||||
auto updateInputLabel = [inputLabel](int value){
|
||||
QString percent = QString::number(value);
|
||||
inputLabel->setText(lng_settings_call_input_volume(lt_percent, percent));
|
||||
const auto inputLabel = content->add(
|
||||
object_ptr<Ui::LabelSimple>(
|
||||
content,
|
||||
st::settingsAudioVolumeLabel),
|
||||
st::settingsAudioVolumeLabelPadding);
|
||||
const auto inputSlider = content->add(
|
||||
object_ptr<Ui::MediaSlider>(
|
||||
content,
|
||||
st::settingsAudioVolumeSlider),
|
||||
st::settingsAudioVolumeSliderPadding);
|
||||
const auto updateInputLabel = [=](int value) {
|
||||
const auto percent = QString::number(value);
|
||||
inputLabel->setText(
|
||||
lng_settings_call_input_volume(lt_percent, percent));
|
||||
};
|
||||
const auto updateInputVolume = [=](int value) {
|
||||
_needWriteSettings = true;
|
||||
updateInputLabel(value);
|
||||
Global::SetCallInputVolume(value);
|
||||
::Calls::Call *currentCall = ::Calls::Current().currentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setAudioVolume(true, value / 100.0f);
|
||||
}
|
||||
};
|
||||
inputSlider->resize(st::settingsAudioVolumeSlider.seekSize);
|
||||
inputSlider->setPseudoDiscrete(101,
|
||||
[](int val){
|
||||
return val;
|
||||
},
|
||||
[](int val) { return val; },
|
||||
Global::CallInputVolume(),
|
||||
[updateInputLabel, this](int value) {
|
||||
_needWriteSettings = true;
|
||||
updateInputLabel(value);
|
||||
Global::SetCallInputVolume(value);
|
||||
::Calls::Call *currentCall = ::Calls::Current().currentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setAudioVolume(true, value / 100.0f);
|
||||
}
|
||||
});
|
||||
updateInputVolume);
|
||||
updateInputLabel(Global::CallInputVolume());
|
||||
|
||||
_micTestButton=AddButton(content, rpl::single(lang(lng_settings_call_test_mic)) | rpl::then(_micTestTextStream.events()), st::settingsButton);
|
||||
|
||||
_micTestLevel=content->add(object_ptr<Ui::LevelMeter>(content, st::defaultLevelMeter), st::settingsLevelMeterPadding);
|
||||
_micTestLevel->resize(QSize(0, st::defaultLevelMeter.height));
|
||||
|
||||
_micTestButton->addClickHandler([this]{
|
||||
AddButton(
|
||||
content,
|
||||
rpl::single(
|
||||
lang(lng_settings_call_test_mic)
|
||||
) | rpl::then(
|
||||
_micTestTextStream.events()
|
||||
),
|
||||
st::settingsButton
|
||||
)->addClickHandler([=] {
|
||||
if (!_micTester) {
|
||||
requestPermissionAndStartTestingMicrophone();
|
||||
} else {
|
||||
stopTestingMicrophone();
|
||||
}
|
||||
});
|
||||
_levelUpdateTimer.setCallback([this](){
|
||||
|
||||
_micTestLevel = content->add(
|
||||
object_ptr<Ui::LevelMeter>(
|
||||
content,
|
||||
st::defaultLevelMeter),
|
||||
st::settingsLevelMeterPadding);
|
||||
_micTestLevel->resize(QSize(0, st::defaultLevelMeter.height));
|
||||
|
||||
_levelUpdateTimer.setCallback([=] {
|
||||
_micTestLevel->setValue(_micTester->GetAndResetLevel());
|
||||
});
|
||||
|
||||
@ -252,16 +290,20 @@ void Calls::setupContent() {
|
||||
}) | rpl::start_with_next([](bool enabled) {
|
||||
Global::SetCallAudioDuckingEnabled(enabled);
|
||||
Local::writeUserSettings();
|
||||
::Calls::Call *currentCall = ::Calls::Current().currentCall();
|
||||
if (currentCall) {
|
||||
currentCall->setAudioDuckingEnabled(enabled);
|
||||
if (const auto call = ::Calls::Current().currentCall()) {
|
||||
call->setAudioDuckingEnabled(enabled);
|
||||
}
|
||||
}, content->lifetime());
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
const auto systemSettingsButton=AddButton(content, lng_settings_call_open_system_prefs, st::settingsButton);
|
||||
systemSettingsButton->addClickHandler([]{
|
||||
if (!Platform::OpenSystemSettings(Platform::SystemSettingsType::Audio)) {
|
||||
AddButton(
|
||||
content,
|
||||
lng_settings_call_open_system_prefs,
|
||||
st::settingsButton
|
||||
)->addClickHandler([] {
|
||||
const auto opened = Platform::OpenSystemSettings(
|
||||
Platform::SystemSettingsType::Audio);
|
||||
if (!opened) {
|
||||
Ui::show(Box<InformBox>(lang(lng_linux_no_audio_prefs)));
|
||||
}
|
||||
});
|
||||
@ -270,37 +312,48 @@ void Calls::setupContent() {
|
||||
Ui::ResizeFitChild(this, content);
|
||||
}
|
||||
|
||||
void Calls::requestPermissionAndStartTestingMicrophone(){
|
||||
Platform::PermissionStatus status = Platform::GetPermissionStatus(Platform::PermissionType::Microphone);
|
||||
void Calls::requestPermissionAndStartTestingMicrophone() {
|
||||
const auto status = Platform::GetPermissionStatus(
|
||||
Platform::PermissionType::Microphone);
|
||||
if (status == Platform::PermissionStatus::Granted) {
|
||||
startTestingMicrophone();
|
||||
} else if (status == Platform::PermissionStatus::CanRequest) {
|
||||
Platform::RequestPermission(Platform::PermissionType::Microphone, crl::guard(this, [this](Platform::PermissionStatus status) {
|
||||
const auto startTestingChecked = crl::guard(this, [=](
|
||||
Platform::PermissionStatus status) {
|
||||
if (status == Platform::PermissionStatus::Granted) {
|
||||
crl::on_main(crl::guard(this, [this]{
|
||||
crl::on_main(crl::guard(this, [=] {
|
||||
startTestingMicrophone();
|
||||
}));
|
||||
}
|
||||
}));
|
||||
});
|
||||
Platform::RequestPermission(
|
||||
Platform::PermissionType::Microphone,
|
||||
startTestingChecked);
|
||||
} else {
|
||||
Ui::show(Box<ConfirmBox>(lang(lng_no_mic_permission), lang(lng_menu_settings), crl::guard(this, [] {
|
||||
Platform::OpenSystemSettingsForPermission(Platform::PermissionType::Microphone);
|
||||
const auto showSystemSettings = [] {
|
||||
Platform::OpenSystemSettingsForPermission(
|
||||
Platform::PermissionType::Microphone);
|
||||
Ui::hideLayer();
|
||||
})));
|
||||
};
|
||||
Ui::show(Box<ConfirmBox>(
|
||||
lang(lng_no_mic_permission),
|
||||
lang(lng_menu_settings),
|
||||
showSystemSettings));
|
||||
}
|
||||
}
|
||||
|
||||
void Calls::startTestingMicrophone(){
|
||||
void Calls::startTestingMicrophone() {
|
||||
_micTestTextStream.fire(lang(lng_settings_call_stop_mic_test));
|
||||
_levelUpdateTimer.callEach(50);
|
||||
_micTester = std::make_unique<tgvoip::AudioInputTester>(Global::CallInputDeviceID().toStdString());
|
||||
_micTester = std::make_unique<tgvoip::AudioInputTester>(
|
||||
Global::CallInputDeviceID().toStdString());
|
||||
if (_micTester->Failed()) {
|
||||
Ui::show(Box<InformBox>(lang(lng_call_error_audio_io)));
|
||||
stopTestingMicrophone();
|
||||
}
|
||||
}
|
||||
|
||||
void Calls::stopTestingMicrophone(){
|
||||
void Calls::stopTestingMicrophone() {
|
||||
_micTestTextStream.fire(lang(lng_settings_call_test_mic));
|
||||
_levelUpdateTimer.cancel();
|
||||
_micTester.reset();
|
||||
|
@ -41,7 +41,6 @@ private:
|
||||
rpl::event_stream<QString> _micTestTextStream;
|
||||
bool _needWriteSettings = false;
|
||||
std::unique_ptr<tgvoip::AudioInputTester> _micTester;
|
||||
Button *_micTestButton = nullptr;
|
||||
Ui::LevelMeter *_micTestLevel = nullptr;
|
||||
base::Timer _levelUpdateTimer;
|
||||
};
|
||||
|
@ -603,11 +603,11 @@ void RadiobuttonGroup::setValue(int value) {
|
||||
}
|
||||
_hasValue = true;
|
||||
_value = value;
|
||||
for (auto button : _buttons) {
|
||||
for (const auto button : _buttons) {
|
||||
button->handleNewGroupValue(_value);
|
||||
}
|
||||
if (_changedCallback) {
|
||||
_changedCallback(_value);
|
||||
if (const auto callback = _changedCallback) {
|
||||
callback(_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,33 +9,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace Ui {
|
||||
|
||||
LevelMeter::LevelMeter(QWidget *parent, const style::LevelMeter &st) : RpWidget(parent), _st(st){
|
||||
|
||||
LevelMeter::LevelMeter(QWidget *parent, const style::LevelMeter &st)
|
||||
: RpWidget(parent)
|
||||
, _st(st) {
|
||||
}
|
||||
|
||||
void LevelMeter::setValue(float value){
|
||||
void LevelMeter::setValue(float value) {
|
||||
_value = value;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void LevelMeter::paintEvent(QPaintEvent* event){
|
||||
void LevelMeter::paintEvent(QPaintEvent* event) {
|
||||
Painter p(this);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
auto activeFg = _st.activeFg;
|
||||
auto inactiveFg = _st.inactiveFg;
|
||||
auto radius = _st.lineWidth / 2;
|
||||
QRect rect(0, 0, _st.lineWidth, height());
|
||||
const auto activeFg = _st.activeFg;
|
||||
const auto inactiveFg = _st.inactiveFg;
|
||||
const auto radius = _st.lineWidth / 2;
|
||||
const auto rect = QRect(0, 0, _st.lineWidth, height());
|
||||
p.setBrush(activeFg);
|
||||
for (auto i = 0; i < _st.lineCount; ++i) {
|
||||
float valueAtLine = (float)(i + 1) / _st.lineCount;
|
||||
const auto valueAtLine = (float)(i + 1) / _st.lineCount;
|
||||
if (valueAtLine > _value) {
|
||||
p.setBrush(inactiveFg);
|
||||
}
|
||||
rect.moveLeft((_st.lineWidth + _st.lineSpacing) * i);
|
||||
p.drawRoundedRect(rect, radius, radius);
|
||||
p.drawRoundedRect(
|
||||
rect.translated((_st.lineWidth + _st.lineSpacing) * i, 0),
|
||||
radius,
|
||||
radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ namespace Ui {
|
||||
class LevelMeter : public RpWidget {
|
||||
public:
|
||||
LevelMeter(QWidget *parent, const style::LevelMeter& st);
|
||||
|
||||
void setValue(float value);
|
||||
|
||||
protected:
|
||||
@ -22,7 +23,8 @@ protected:
|
||||
|
||||
private:
|
||||
const style::LevelMeter &_st;
|
||||
float _value=0.0f;
|
||||
float _value = 0.0f;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
Loading…
Reference in New Issue
Block a user