Add toggle video and screen sharing buttons.

This commit is contained in:
John Preston 2021-04-27 16:03:36 +04:00
parent e0bfaad3a2
commit b7fc3f67d7
11 changed files with 151 additions and 115 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1998,6 +1998,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_raised_hand_status" = "wants to speak";
"lng_group_call_settings" = "Settings";
"lng_group_call_share_button" = "Share";
"lng_group_call_video" = "Video";
"lng_group_call_screen_share" = "Share";
"lng_group_call_unmute_small" = "Unmute";
"lng_group_call_you_are_live_small" = "Mute";

View File

@ -200,7 +200,7 @@ callMuteButtonActiveInner: IconButton {
}
callMuteButtonSmallActiveInner: IconButton {
width: 68px;
height: 79px;
height: 76px;
}
callMuteButtonActive: CallButton {
button: callMuteButtonActiveInner;
@ -289,55 +289,6 @@ callRemoteAudioMute: FlatLabel(callStatus) {
}
callRemoteAudioMuteSkip: 12px;
callMuteMainBlobMinRadius: 57px;
callMuteMainBlobMaxRadius: 63px;
callMuteMinorBlobMinRadius: 64px;
callMuteMinorBlobMaxRadius: 74px;
callMuteMajorBlobMinRadius: 67px;
callMuteMajorBlobMaxRadius: 77px;
callMuteButtonActiveInner: IconButton {
width: 136px;
height: 165px;
}
callMuteButtonLabel: FlatLabel(defaultFlatLabel) {
textFg: groupCallMembersFg;
style: TextStyle(defaultTextStyle) {
font: font(14px);
linkFont: font(14px);
linkFontOver: font(14px underline);
}
}
callMuteButtonSublabel: FlatLabel(defaultFlatLabel) {
textFg: groupCallMemberNotJoinedStatus;
}
callMuteButtonLabelsSkip: 5px;
callMuteButtonSublabelSkip: 19px;
callMuteButtonActive: CallButton {
button: callMuteButtonActiveInner;
bg: groupCallLive1;
bgSize: 100px;
bgPosition: point(18px, 18px);
outerRadius: 18px;
outerBg: callAnswerBgOuter;
label: callMuteButtonLabel;
}
callMuteButtonMuted: CallButton(callMuteButtonActive) {
bg: groupCallMuted1;
label: callMuteButtonLabel;
}
callMuteButtonConnecting: CallButton(callMuteButtonMuted) {
bg: callIconBg;
label: callMuteButtonLabel;
}
callMuteButtonLabelAdditional: 5px;
callConnectingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
color: lightButtonFg;
thickness: 4px;
size: size(100px, 100px);
}
callBarHeight: 38px;
callBarMuteToggle: IconButton {
width: 41px;
@ -820,27 +771,67 @@ groupCallSettingsInner: IconButton(callButton) {
color: callMuteRipple;
}
}
groupCallShareInner: IconButton(groupCallSettingsInner) {
icon: icon {{ "calls/group_calls_share", groupCallIconFg }};
}
groupCallHangupInner: IconButton(callButton) {
icon: icon {{ "calls/call_discard", groupCallIconFg }};
ripple: RippleAnimation(defaultRippleAnimation) {
color: groupCallLeaveBgRipple;
}
}
groupCallSettings: CallButton(callMicrophoneMute) {
button: groupCallSettingsInner;
}
groupCallShare: CallButton(groupCallSettings) {
button: IconButton(groupCallSettingsInner) {
icon: icon {{ "calls/group_calls_share", groupCallIconFg }};
}
button: groupCallShareInner;
}
groupCallHangup: CallButton(callHangup) {
button: IconButton(callButton) {
icon: icon {{ "calls/call_discard", groupCallIconFg }};
ripple: RippleAnimation(defaultRippleAnimation) {
color: groupCallLeaveBgRipple;
}
}
button: groupCallHangupInner;
bg: groupCallLeaveBg;
outerBg: groupCallLeaveBg;
label: callButtonLabel;
}
groupCallSettingsSmall: CallButton(groupCallSettings) {
button: IconButton(groupCallSettingsInner) {
height: 76px;
}
}
groupCallShareSmall: CallButton(groupCallShare) {
button: IconButton(groupCallShareInner) {
height: 76px;
}
}
groupCallHangupSmall: CallButton(groupCallHangup) {
button: IconButton(groupCallHangupInner) {
height: 76px;
}
}
groupCallVideoSmallInner: IconButton(groupCallSettingsInner) {
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
iconPosition: point(-1px, 16px);
ripple: RippleAnimation(defaultRippleAnimation) {
color: groupCallLeaveBgRipple;
}
height: 76px;
}
groupCallVideoSmall: CallButton(groupCallShareSmall) {
button: groupCallVideoSmallInner;
}
groupCallVideoActiveSmall: CallButton(groupCallVideoSmall) {
button: IconButton(groupCallVideoSmallInner) {
icon: icon {{ "calls/call_camera_active", groupCallIconFg }};
}
}
groupCallScreenShareSmall: CallButton(groupCallShareSmall) {
button: IconButton(groupCallSettingsInner) {
icon: icon {{ "calls/calls_present", groupCallIconFg }};
}
}
groupCallButtonSkip: 43px;
groupCallButtonSkipSmall: 4px;
groupCallButtonBottomSkip: 145px;
groupCallButtonBottomSkipSmall: 95px;
groupCallMuteBottomSkip: 160px;
groupCallTopBarUserpics: GroupCallUserpics {

View File

@ -405,15 +405,24 @@ bool GroupCall::isScreenSharing() const {
return (_videoDeviceId != _videoInputId);
}
void GroupCall::switchToCamera() {
if (!_videoCapture || !isScreenSharing()) {
void GroupCall::toggleVideo(bool active) {
if (!active) {
if (!isScreenSharing()) {
_videoOutgoing->setState(Webrtc::VideoState::Inactive);
}
return;
}
const auto changing = isScreenSharing();
_videoDeviceId = _videoInputId;
if (_videoOutgoing->state() != Webrtc::VideoState::Active) {
_videoOutgoing->setState(Webrtc::VideoState::Active);
}
_videoCapture->switchToDevice(_videoDeviceId.toStdString());
if (!_videoCapture) {
return;
}
if (changing) {
_videoCapture->switchToDevice(_videoDeviceId.toStdString());
}
}
void GroupCall::switchToScreenSharing(const QString &uniqueId) {

View File

@ -244,7 +244,7 @@ public:
void setCurrentAudioDevice(bool input, const QString &deviceId);
void setCurrentVideoDevice(const QString &deviceId);
bool isScreenSharing() const;
void switchToCamera();
void toggleVideo(bool active);
void switchToScreenSharing(const QString &uniqueId);
void toggleMute(const Group::MuteRequest &data);

View File

@ -685,30 +685,47 @@ void Panel::refreshLeftButton() {
const auto share = _call->scheduleDate()
&& _peer->isBroadcast()
&& _peer->asChannel()->hasUsername();
if ((share && _share) || (!share && _settings)) {
if ((share && _callShare) || (!share && _settings)) {
return;
}
if (share) {
_settings.destroy();
_share.create(widget(), st::groupCallShare);
_share->setClickedCallback(_shareLinkCallback);
_share->setText(tr::lng_group_call_share_button());
_callShare.create(widget(), st::groupCallShare);
_callShare->setClickedCallback(_callShareLinkCallback);
_callShare->setText(tr::lng_group_call_share_button());
} else {
_share.destroy();
_callShare.destroy();
_settings.create(widget(), st::groupCallSettings);
_settings->setClickedCallback([=] {
if (_call->isScreenSharing()) {
_call->switchToCamera();
} else {
Ui::DesktopCapture::ChooseSource(this);
}
//_layerBg->showBox(Box(SettingsBox, _call));
_layerBg->showBox(Box(SettingsBox, _call));
});
_settings->setText(tr::lng_group_call_settings());
}
const auto raw = _share ? _share.data() : _settings.data();
const auto raw = _callShare ? _callShare.data() : _settings.data();
raw->show();
raw->setColorOverrides(_mute->colorOverrides());
if (!_video) {
_video.create(widget(), st::groupCallVideoSmall);
_video->show();
_video->setClickedCallback([=] {
const auto sharing = _call->isScreenSharing();
const auto active = (_call->outgoingVideoTrack()->state()
== Webrtc::VideoState::Active);
_call->toggleVideo(sharing || !active);
});
_video->setText(tr::lng_group_call_video());
_video->setColorOverrides(_mute->colorOverrides());
}
if (!_screenShare) {
_screenShare.create(widget(), st::groupCallScreenShareSmall);
_screenShare->show();
_screenShare->setClickedCallback([=] {
Ui::DesktopCapture::ChooseSource(this);
});
_screenShare->setText(tr::lng_group_call_screen_share());
_screenShare->setColorOverrides(_mute->colorOverrides());
}
}
void Panel::initShareAction() {
@ -725,7 +742,7 @@ void Panel::initShareAction() {
_peer,
showBox,
showToast);
_shareLinkCallback = [=, callback = std::move(shareLinkCallback)] {
_callShareLinkCallback = [=, callback = std::move(shareLinkCallback)] {
if (_call->lookupReal()) {
callback();
}
@ -911,7 +928,7 @@ void Panel::setupMembers() {
_members->addMembersRequests(
) | rpl::start_with_next([=] {
if (_peer->isBroadcast() && _peer->asChannel()->hasUsername()) {
_shareLinkCallback();
_callShareLinkCallback();
} else {
addMembers();
}
@ -1505,31 +1522,44 @@ bool Panel::updateMode() {
}
void Panel::updateControlsGeometry() {
if (widget()->size().isEmpty() || (!_settings && !_share)) {
if (widget()->size().isEmpty() || (!_settings && !_callShare)) {
return;
}
if (_videoMode.current()) {
_mute->setStyle(st::callMuteButtonSmall);
const auto buttonsTop = widget()->height()
- st::groupCallButtonBottomSkip;
const auto muteSize = _mute->innerSize().width();
const auto fullWidth = muteSize
+ 2 * (_settings ? _settings : _share)->width()
+ 2 * st::groupCallButtonSkip;
const auto leftButtonLeft = (widget()->width() - fullWidth) / 2;
- st::groupCallButtonBottomSkipSmall;
const auto addSkip = st::callMuteButtonSmall.active.outerRadius;
_mute->moveInner({ leftButtonLeft + addSkip, buttonsTop + addSkip });
const auto muteSize = _mute->innerSize().width() + 2 * addSkip;
const auto skip = (_video ? 1 : 2) * st::groupCallButtonSkipSmall;
const auto fullWidth = muteSize
+ (_video ? _video->width() + skip : 0)
+ (_screenShare ? _screenShare->width() + skip : 0)
+ (_settings ? _settings : _callShare)->width() + skip
+ _hangup->width() + skip;
auto left = (widget()->width() - fullWidth) / 2;
_mute->moveInner({ left + addSkip, buttonsTop + addSkip });
left += muteSize + skip;
if (_video) {
_video->moveToLeft(left, buttonsTop);
left += _video->width() + skip;
}
if (_screenShare) {
_screenShare->moveToLeft(left, buttonsTop);
left += _video->width() + skip;
}
if (_settings) {
_settings->moveToLeft(
(widget()->width() - _settings->width()) / 2,
buttonsTop);
_settings->setStyle(st::groupCallSettingsSmall);
_settings->moveToLeft(left, buttonsTop);
left += _settings->width() + skip;
}
if (_share) {
_share->moveToLeft(
(widget()->width() - _share->width()) / 2,
buttonsTop);
if (_callShare) {
_callShare->setStyle(st::groupCallShareSmall);
_callShare->moveToLeft(left, buttonsTop);
left += _callShare->width() + skip;
}
_hangup->moveToRight(leftButtonLeft, buttonsTop);
_hangup->setStyle(st::groupCallHangupSmall);
_hangup->moveToLeft(left, buttonsTop);
} else {
_mute->setStyle(st::callMuteButton);
const auto muteTop = widget()->height()
@ -1538,16 +1568,19 @@ void Panel::updateControlsGeometry() {
- st::groupCallButtonBottomSkip;
const auto muteSize = _mute->innerSize().width();
const auto fullWidth = muteSize
+ 2 * (_settings ? _settings : _share)->width()
+ 2 * (_settings ? _settings : _callShare)->width()
+ 2 * st::groupCallButtonSkip;
_mute->moveInner({ (widget()->width() - muteSize) / 2, muteTop });
const auto leftButtonLeft = (widget()->width() - fullWidth) / 2;
if (_settings) {
_settings->setStyle(st::groupCallSettings);
_settings->moveToLeft(leftButtonLeft, buttonsTop);
}
if (_share) {
_share->moveToLeft(leftButtonLeft, buttonsTop);
if (_callShare) {
_callShare->setStyle(st::groupCallShare);
_callShare->moveToLeft(leftButtonLeft, buttonsTop);
}
_hangup->setStyle(st::groupCallHangup);
_hangup->moveToRight(leftButtonLeft, buttonsTop);
}
updateMembersGeometry();

View File

@ -147,12 +147,12 @@ private:
rpl::variable<bool> _videoMode;
object_ptr<Ui::CallButton> _settings = { nullptr };
object_ptr<Ui::CallButton> _share = { nullptr };
object_ptr<Ui::CallButton> _callShare = { nullptr };
object_ptr<Ui::CallButton> _video = { nullptr };
object_ptr<Ui::CallButton> _shareScreen = { nullptr };
object_ptr<Ui::CallButton> _screenShare = { nullptr };
std::unique_ptr<Ui::CallMuteButton> _mute;
object_ptr<Ui::CallButton> _hangup;
Fn<void()> _shareLinkCallback;
Fn<void()> _callShareLinkCallback;
rpl::lifetime _peerLifetime;

View File

@ -175,11 +175,9 @@ public:
int additionalHeight,
const style::FlatLabel &st = st::defaultFlatLabel);
int height() const;
int contentHeight() const;
private:
int realHeight() const;
void setText(const QString &text);
const style::FlatLabel &_st;
@ -220,9 +218,9 @@ AnimatedLabel::AnimatedLabel(
p.setPen(_st.textFg);
p.setTextPalette(_st.palette);
const auto textHeight = height();
const auto diffHeight = realHeight() - textHeight;
const auto center = (diffHeight) / 2;
const auto textHeight = contentHeight();
const auto diffHeight = height() - textHeight;
const auto center = diffHeight / 2;
p.setOpacity(1. - progress);
if (p.opacity()) {
@ -246,14 +244,10 @@ AnimatedLabel::AnimatedLabel(
}, lifetime());
}
int AnimatedLabel::height() const {
int AnimatedLabel::contentHeight() const {
return _st.style.font->height;
}
int AnimatedLabel::realHeight() const {
return RpWidget::height();
}
void AnimatedLabel::setText(const QString &text) {
if (_text.toString() == text) {
return;
@ -264,7 +258,9 @@ void AnimatedLabel::setText(const QString &text) {
const auto width = std::max(
_st.style.font->width(_text.toString()),
_st.style.font->width(_previousText.toString()));
resize(width + _additionalHeight, height() + _additionalHeight * 2);
resize(
width + _additionalHeight,
contentHeight() + _additionalHeight * 2);
_animation.stop();
_animation.start([=] { update(); }, 0., 1., _duration);
@ -933,25 +929,31 @@ void CallMuteButton::updateLabelsGeometry() {
void CallMuteButton::updateLabelGeometry(QRect my, QSize size) {
const auto skip = _st->sublabelSkip + _st->labelsSkip;
const auto contentHeight = _label->contentHeight();
const auto contentTop = my.y() + my.height() - contentHeight - skip;
_label->moveToLeft(
my.x() + (my.width() - size.width()) / 2 + _labelShakeShift,
my.y() + my.height() - size.height() - skip,
contentTop - (size.height() - contentHeight) / 2,
my.width());
}
void CallMuteButton::updateCenterLabelGeometry(QRect my, QSize size) {
const auto skip = (_st->sublabelSkip / 2) + _st->labelsSkip;
const auto contentHeight = _centerLabel->contentHeight();
const auto contentTop = my.y() + my.height() - contentHeight - skip;
_centerLabel->moveToLeft(
my.x() + (my.width() - size.width()) / 2 + _labelShakeShift,
my.y() + my.height() - size.height() - skip,
contentTop - (size.height() - contentHeight) / 2,
my.width());
}
void CallMuteButton::updateSublabelGeometry(QRect my, QSize size) {
const auto skip = _st->labelsSkip;
const auto contentHeight = _sublabel->contentHeight();
const auto contentTop = my.y() + my.height() - contentHeight - skip;
_sublabel->moveToLeft(
my.x() + (my.width() - size.width()) / 2 + _labelShakeShift,
my.y() + my.height() - size.height() - skip,
contentTop - (size.height() - contentHeight) / 2,
my.width());
}

@ -1 +1 @@
Subproject commit 14c67cf724a572186455a8c0639f037ae26cc762
Subproject commit 3c1866f52d88f9430341f9a9f1ed3dbbb3b794ea