Add toggle video and screen sharing buttons.
This commit is contained in:
parent
e0bfaad3a2
commit
b7fc3f67d7
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 |
|
@ -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";
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue