mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Implement menu in wide video mode.
This commit is contained in:
parent
1c42513e44
commit
45cca35724
7 changed files with 194 additions and 78 deletions
|
@ -739,6 +739,7 @@ groupCallJoinAsToggle: UserpicButton(defaultUserpicButton) {
|
||||||
photoPosition: point(3px, 3px);
|
photoPosition: point(3px, 3px);
|
||||||
}
|
}
|
||||||
groupCallMenuPosition: point(-1px, 29px);
|
groupCallMenuPosition: point(-1px, 29px);
|
||||||
|
groupCallWideMenuPosition: point(-2px, 28px);
|
||||||
|
|
||||||
groupCallActiveButton: IconButton {
|
groupCallActiveButton: IconButton {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
|
@ -848,6 +849,14 @@ groupCallScreenShareSmall: CallButton(groupCallSettingsSmall) {
|
||||||
rippleAreaPosition: point(8px, 12px);
|
rippleAreaPosition: point(8px, 12px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
groupCallMenuToggleSmall: CallButton(groupCallSettingsSmall) {
|
||||||
|
button: IconButton(groupCallSettingsInner) {
|
||||||
|
icon: icon {{ "calls/calls_more", groupCallIconFg }};
|
||||||
|
width: 60px;
|
||||||
|
height: 68px;
|
||||||
|
rippleAreaPosition: point(8px, 12px);
|
||||||
|
}
|
||||||
|
}
|
||||||
groupCallButtonSkip: 40px;
|
groupCallButtonSkip: 40px;
|
||||||
groupCallButtonSkipSmall: 5px;
|
groupCallButtonSkipSmall: 5px;
|
||||||
groupCallButtonBottomSkip: 113px;
|
groupCallButtonBottomSkip: 113px;
|
||||||
|
|
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "base/global_shortcuts.h"
|
#include "base/global_shortcuts.h"
|
||||||
#include "base/openssl_help.h"
|
#include "base/openssl_help.h"
|
||||||
|
@ -364,6 +365,7 @@ GroupCall::GroupCall(
|
||||||
, _joinAs(info.joinAs)
|
, _joinAs(info.joinAs)
|
||||||
, _possibleJoinAs(std::move(info.possibleJoinAs))
|
, _possibleJoinAs(std::move(info.possibleJoinAs))
|
||||||
, _joinHash(info.joinHash)
|
, _joinHash(info.joinHash)
|
||||||
|
, _canManage(Data::CanManageGroupCallValue(_peer))
|
||||||
, _id(inputCall.c_inputGroupCall().vid().v)
|
, _id(inputCall.c_inputGroupCall().vid().v)
|
||||||
, _scheduleDate(info.scheduleDate)
|
, _scheduleDate(info.scheduleDate)
|
||||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||||
|
@ -399,7 +401,7 @@ GroupCall::GroupCall(
|
||||||
|
|
||||||
if (const auto real = lookupReal()) {
|
if (const auto real = lookupReal()) {
|
||||||
subscribeToReal(real);
|
subscribeToReal(real);
|
||||||
if (!_peer->canManageGroupCall() && real->joinMuted()) {
|
if (!canManage() && real->joinMuted()) {
|
||||||
_muted = MuteState::ForceMuted;
|
_muted = MuteState::ForceMuted;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -472,6 +474,14 @@ bool GroupCall::mutedByAdmin() const {
|
||||||
return mute == MuteState::ForceMuted || mute == MuteState::RaisedHand;
|
return mute == MuteState::ForceMuted || mute == MuteState::RaisedHand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GroupCall::canManage() const {
|
||||||
|
return _canManage.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> GroupCall::canManageValue() const {
|
||||||
|
return _canManage.value();
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::toggleVideo(bool active) {
|
void GroupCall::toggleVideo(bool active) {
|
||||||
if (!_instance
|
if (!_instance
|
||||||
|| !_id
|
|| !_id
|
||||||
|
@ -758,6 +768,7 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
||||||
_peerStream.events_starting_with_copy(_peer));
|
_peerStream.events_starting_with_copy(_peer));
|
||||||
SubscribeToMigration(_peer, _lifetime, [=](not_null<ChannelData*> group) {
|
SubscribeToMigration(_peer, _lifetime, [=](not_null<ChannelData*> group) {
|
||||||
_peer = group;
|
_peer = group;
|
||||||
|
_canManage = Data::CanManageGroupCallValue(_peer);
|
||||||
_peerStream.fire_copy(group);
|
_peerStream.fire_copy(group);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1135,7 @@ void GroupCall::applyParticipantLocally(
|
||||||
if (!participant || !participant->ssrc) {
|
if (!participant || !participant->ssrc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto canManageCall = _peer->canManageGroupCall();
|
const auto canManageCall = canManage();
|
||||||
const auto isMuted = participant->muted || (mute && canManageCall);
|
const auto isMuted = participant->muted || (mute && canManageCall);
|
||||||
const auto canSelfUnmute = !canManageCall
|
const auto canSelfUnmute = !canManageCall
|
||||||
? participant->canSelfUnmute
|
? participant->canSelfUnmute
|
||||||
|
@ -1705,7 +1716,6 @@ void GroupCall::ensureControllerCreated() {
|
||||||
|
|
||||||
const auto weak = base::make_weak(&_instanceGuard);
|
const auto weak = base::make_weak(&_instanceGuard);
|
||||||
const auto myLevel = std::make_shared<tgcalls::GroupLevelValue>();
|
const auto myLevel = std::make_shared<tgcalls::GroupLevelValue>();
|
||||||
_videoCall = true;
|
|
||||||
tgcalls::GroupInstanceDescriptor descriptor = {
|
tgcalls::GroupInstanceDescriptor descriptor = {
|
||||||
.threads = tgcalls::StaticThreads::getThreads(),
|
.threads = tgcalls::StaticThreads::getThreads(),
|
||||||
.config = tgcalls::GroupConfig{
|
.config = tgcalls::GroupConfig{
|
||||||
|
|
|
@ -238,13 +238,6 @@ public:
|
||||||
return _muted.value();
|
return _muted.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool videoCall() const {
|
|
||||||
return _videoCall.current();
|
|
||||||
}
|
|
||||||
[[nodiscard]] rpl::producer<bool> videoCallValue() const {
|
|
||||||
return _videoCall.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto otherParticipantStateValue() const
|
[[nodiscard]] auto otherParticipantStateValue() const
|
||||||
-> rpl::producer<Group::ParticipantState>;
|
-> rpl::producer<Group::ParticipantState>;
|
||||||
|
|
||||||
|
@ -328,6 +321,9 @@ public:
|
||||||
static constexpr auto kSpeakLevelThreshold = 0.2;
|
static constexpr auto kSpeakLevelThreshold = 0.2;
|
||||||
|
|
||||||
[[nodiscard]] bool mutedByAdmin() const;
|
[[nodiscard]] bool mutedByAdmin() const;
|
||||||
|
[[nodiscard]] bool canManage() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> canManageValue() const;
|
||||||
|
|
||||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||||
void setCurrentVideoDevice(const QString &deviceId);
|
void setCurrentVideoDevice(const QString &deviceId);
|
||||||
[[nodiscard]] bool isSharingScreen() const;
|
[[nodiscard]] bool isSharingScreen() const;
|
||||||
|
@ -491,7 +487,7 @@ private:
|
||||||
QString _joinHash;
|
QString _joinHash;
|
||||||
|
|
||||||
rpl::variable<MuteState> _muted = MuteState::Muted;
|
rpl::variable<MuteState> _muted = MuteState::Muted;
|
||||||
rpl::variable<bool> _videoCall = false;
|
rpl::variable<bool> _canManage = false;
|
||||||
bool _initialMuteStateSent = false;
|
bool _initialMuteStateSent = false;
|
||||||
bool _acceptFields = false;
|
bool _acceptFields = false;
|
||||||
|
|
||||||
|
|
|
@ -590,7 +590,9 @@ void FillMenu(
|
||||||
not_null<Ui::DropdownMenu*> menu,
|
not_null<Ui::DropdownMenu*> menu,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
not_null<GroupCall*> call,
|
not_null<GroupCall*> call,
|
||||||
|
bool wide,
|
||||||
Fn<void()> chooseJoinAs,
|
Fn<void()> chooseJoinAs,
|
||||||
|
Fn<void()> chooseShareScreenSource,
|
||||||
Fn<void(object_ptr<Ui::BoxContent>)> showBox) {
|
Fn<void(object_ptr<Ui::BoxContent>)> showBox) {
|
||||||
const auto weak = base::make_weak(call.get());
|
const auto weak = base::make_weak(call.get());
|
||||||
const auto resolveReal = [=] {
|
const auto resolveReal = [=] {
|
||||||
|
@ -606,9 +608,10 @@ void FillMenu(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto addEditJoinAs = call->showChooseJoinAs();
|
const auto addEditJoinAs = call->showChooseJoinAs();
|
||||||
const auto addEditTitle = peer->canManageGroupCall();
|
const auto addEditTitle = call->canManage();
|
||||||
const auto addEditRecording = peer->canManageGroupCall()
|
const auto addEditRecording = call->canManage() && !real->scheduleDate();
|
||||||
&& !real->scheduleDate();
|
const auto addScreenCast = !wide
|
||||||
|
&& (real->canStartVideo() || call->isSharingScreen());
|
||||||
if (addEditJoinAs) {
|
if (addEditJoinAs) {
|
||||||
menu->addAction(MakeJoinAsAction(
|
menu->addAction(MakeJoinAsAction(
|
||||||
menu->menu(),
|
menu->menu(),
|
||||||
|
@ -660,6 +663,23 @@ void FillMenu(
|
||||||
real->recordStartDateValue(),
|
real->recordStartDateValue(),
|
||||||
handler));
|
handler));
|
||||||
}
|
}
|
||||||
|
if (addScreenCast) {
|
||||||
|
const auto sharing = call->isSharingScreen();
|
||||||
|
const auto toggle = [=] {
|
||||||
|
if (const auto strong = weak.get()) {
|
||||||
|
if (sharing) {
|
||||||
|
strong->toggleScreenSharing(std::nullopt);
|
||||||
|
} else {
|
||||||
|
chooseShareScreenSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
menu->addAction(
|
||||||
|
(call->isSharingScreen()
|
||||||
|
? tr::lng_group_call_screen_share_stop(tr::now)
|
||||||
|
: tr::lng_group_call_screen_share_start(tr::now)),
|
||||||
|
toggle);
|
||||||
|
}
|
||||||
menu->addAction(tr::lng_group_call_settings(tr::now), [=] {
|
menu->addAction(tr::lng_group_call_settings(tr::now), [=] {
|
||||||
if (const auto strong = weak.get()) {
|
if (const auto strong = weak.get()) {
|
||||||
showBox(Box(SettingsBox, strong));
|
showBox(Box(SettingsBox, strong));
|
||||||
|
@ -677,8 +697,12 @@ void FillMenu(
|
||||||
menu->addAction(MakeAttentionAction(
|
menu->addAction(MakeAttentionAction(
|
||||||
menu->menu(),
|
menu->menu(),
|
||||||
(real->scheduleDate()
|
(real->scheduleDate()
|
||||||
? tr::lng_group_call_cancel(tr::now)
|
? (call->canManage()
|
||||||
: tr::lng_group_call_end(tr::now)),
|
? tr::lng_group_call_cancel(tr::now)
|
||||||
|
: tr::lng_group_call_leave(tr::now))
|
||||||
|
: (call->canManage()
|
||||||
|
? tr::lng_group_call_end(tr::now)
|
||||||
|
: tr::lng_group_call_leave(tr::now))),
|
||||||
finish));
|
finish));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,9 @@ void FillMenu(
|
||||||
not_null<Ui::DropdownMenu*> menu,
|
not_null<Ui::DropdownMenu*> menu,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
not_null<GroupCall*> call,
|
not_null<GroupCall*> call,
|
||||||
|
bool wide,
|
||||||
Fn<void()> chooseJoinAs,
|
Fn<void()> chooseJoinAs,
|
||||||
|
Fn<void()> chooseShareScreenSource,
|
||||||
Fn<void(object_ptr<Ui::BoxContent>)> showBox);
|
Fn<void(object_ptr<Ui::BoxContent>)> showBox);
|
||||||
|
|
||||||
[[nodiscard]] base::unique_qptr<Ui::Menu::ItemBase> MakeAttentionAction(
|
[[nodiscard]] base::unique_qptr<Ui::Menu::ItemBase> MakeAttentionAction(
|
||||||
|
|
|
@ -38,7 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_peer_values.h"
|
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "base/event_filter.h"
|
#include "base/event_filter.h"
|
||||||
#include "boxes/peers/edit_participants_box.h"
|
#include "boxes/peers/edit_participants_box.h"
|
||||||
|
@ -555,9 +554,7 @@ void Panel::initWindow() {
|
||||||
: Flag::None;
|
: Flag::None;
|
||||||
});
|
});
|
||||||
|
|
||||||
rpl::combine(
|
_call->hasVideoWithFramesValue(
|
||||||
_call->hasVideoWithFramesValue(),
|
|
||||||
_call->videoCallValue()
|
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
updateMode();
|
updateMode();
|
||||||
}, _window->lifetime());
|
}, _window->lifetime());
|
||||||
|
@ -584,7 +581,7 @@ void Panel::initWidget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::endCall() {
|
void Panel::endCall() {
|
||||||
if (!_call->peer()->canManageGroupCall()) {
|
if (!_call->canManage()) {
|
||||||
_call->hangup();
|
_call->hangup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -626,7 +623,7 @@ void Panel::initControls() {
|
||||||
return (button == Qt::LeftButton);
|
return (button == Qt::LeftButton);
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
if (_call->scheduleDate()) {
|
if (_call->scheduleDate()) {
|
||||||
if (_peer->canManageGroupCall()) {
|
if (_call->canManage()) {
|
||||||
startScheduledNow();
|
startScheduledNow();
|
||||||
} else if (const auto real = _call->lookupReal()) {
|
} else if (const auto real = _call->lookupReal()) {
|
||||||
_call->toggleScheduleStartSubscribed(
|
_call->toggleScheduleStartSubscribed(
|
||||||
|
@ -649,6 +646,13 @@ void Panel::initControls() {
|
||||||
refreshLeftButton();
|
refreshLeftButton();
|
||||||
refreshVideoButtons();
|
refreshVideoButtons();
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
_mode.value(),
|
||||||
|
_call->canManageValue()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
refreshTopButton();
|
||||||
|
}, widget()->lifetime());
|
||||||
|
|
||||||
_hangup->setClickedCallback([=] { endCall(); });
|
_hangup->setClickedCallback([=] { endCall(); });
|
||||||
|
|
||||||
const auto scheduleDate = _call->scheduleDate();
|
const auto scheduleDate = _call->scheduleDate();
|
||||||
|
@ -730,6 +734,7 @@ void Panel::refreshLeftButton() {
|
||||||
const auto raw = _callShare ? _callShare.data() : _settings.data();
|
const auto raw = _callShare ? _callShare.data() : _settings.data();
|
||||||
raw->show();
|
raw->show();
|
||||||
raw->setColorOverrides(_mute->colorOverrides());
|
raw->setColorOverrides(_mute->colorOverrides());
|
||||||
|
updateButtonsStyles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
|
void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
|
||||||
|
@ -783,7 +788,7 @@ void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
|
||||||
_screenShare.create(widget(), st::groupCallScreenShareSmall);
|
_screenShare.create(widget(), st::groupCallScreenShareSmall);
|
||||||
_screenShare->show();
|
_screenShare->show();
|
||||||
_screenShare->setClickedCallback([=] {
|
_screenShare->setClickedCallback([=] {
|
||||||
Ui::DesktopCapture::ChooseSource(this);
|
chooseShareScreenSource();
|
||||||
});
|
});
|
||||||
_screenShare->setColorOverrides(
|
_screenShare->setColorOverrides(
|
||||||
toggleableOverrides(_call->isSharingScreenValue()));
|
toggleableOverrides(_call->isSharingScreenValue()));
|
||||||
|
@ -792,6 +797,13 @@ void Panel::refreshVideoButtons(std::optional<bool> overrideWideMode) {
|
||||||
_screenShare->setProgress(sharing ? 1. : 0.);
|
_screenShare->setProgress(sharing ? 1. : 0.);
|
||||||
}, _screenShare->lifetime());
|
}, _screenShare->lifetime());
|
||||||
}
|
}
|
||||||
|
if (!_wideMenu) {
|
||||||
|
_wideMenu.create(widget(), st::groupCallMenuToggleSmall);
|
||||||
|
_wideMenu->show();
|
||||||
|
_wideMenu->setClickedCallback([=] { showMainMenu(); });
|
||||||
|
_wideMenu->setColorOverrides(
|
||||||
|
toggleableOverrides(_wideMenuShown.value()));
|
||||||
|
}
|
||||||
updateButtonsStyles();
|
updateButtonsStyles();
|
||||||
updateButtonsGeometry();
|
updateButtonsGeometry();
|
||||||
}
|
}
|
||||||
|
@ -825,7 +837,7 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
|
||||||
_call->instanceStateValue(),
|
_call->instanceStateValue(),
|
||||||
real->scheduleDateValue(),
|
real->scheduleDateValue(),
|
||||||
real->scheduleStartSubscribedValue(),
|
real->scheduleStartSubscribedValue(),
|
||||||
Data::CanManageGroupCallValue(_peer),
|
_call->canManageValue(),
|
||||||
_mode.value()
|
_mode.value()
|
||||||
) | rpl::distinct_until_changed(
|
) | rpl::distinct_until_changed(
|
||||||
) | rpl::filter(
|
) | rpl::filter(
|
||||||
|
@ -1103,6 +1115,7 @@ void Panel::raiseControls() {
|
||||||
&_settings,
|
&_settings,
|
||||||
&_callShare,
|
&_callShare,
|
||||||
&_screenShare,
|
&_screenShare,
|
||||||
|
&_wideMenu,
|
||||||
&_video,
|
&_video,
|
||||||
&_hangup
|
&_hangup
|
||||||
};
|
};
|
||||||
|
@ -1323,16 +1336,37 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||||
}, widget()->lifetime());
|
}, widget()->lifetime());
|
||||||
validateRecordingMark(real->recordStartDate() != 0);
|
validateRecordingMark(real->recordStartDate() != 0);
|
||||||
|
|
||||||
const auto showMenu = _peer->canManageGroupCall();
|
real->canStartVideoValue(
|
||||||
const auto showUserpic = !showMenu && _call->showChooseJoinAs();
|
) | rpl::start_with_next([=] {
|
||||||
if (showMenu) {
|
refreshVideoButtons();
|
||||||
|
refreshTopButton();
|
||||||
|
}, widget()->lifetime());
|
||||||
|
|
||||||
|
updateControlsGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::refreshTopButton() {
|
||||||
|
if (_mode.current() == PanelMode::Wide) {
|
||||||
|
_menuToggle.destroy();
|
||||||
|
_joinAsToggle.destroy();
|
||||||
|
updateButtonsGeometry(); // _wideMenu <-> _settings
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto real = _call->lookupReal();
|
||||||
|
const auto hasJoinAs = _call->showChooseJoinAs();
|
||||||
|
const auto wide = (_mode.current() == PanelMode::Wide);
|
||||||
|
const auto showNarrowMenu = _call->canManage()
|
||||||
|
|| (real && real->canStartVideo());
|
||||||
|
const auto showNarrowUserpic = !showNarrowMenu && hasJoinAs;
|
||||||
|
if (showNarrowMenu) {
|
||||||
_joinAsToggle.destroy();
|
_joinAsToggle.destroy();
|
||||||
if (!_menuToggle) {
|
if (!_menuToggle) {
|
||||||
_menuToggle.create(widget(), st::groupCallMenuToggle);
|
_menuToggle.create(widget(), st::groupCallMenuToggle);
|
||||||
_menuToggle->show();
|
_menuToggle->show();
|
||||||
_menuToggle->setClickedCallback([=] { showMainMenu(); });
|
_menuToggle->setClickedCallback([=] { showMainMenu(); });
|
||||||
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
} else if (showUserpic) {
|
} else if (showNarrowUserpic) {
|
||||||
_menuToggle.destroy();
|
_menuToggle.destroy();
|
||||||
rpl::single(
|
rpl::single(
|
||||||
_call->joinAs()
|
_call->joinAs()
|
||||||
|
@ -1357,12 +1391,10 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||||
_menuToggle.destroy();
|
_menuToggle.destroy();
|
||||||
_joinAsToggle.destroy();
|
_joinAsToggle.destroy();
|
||||||
}
|
}
|
||||||
real->canStartVideoValue(
|
}
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
refreshVideoButtons();
|
|
||||||
}, widget()->lifetime());
|
|
||||||
|
|
||||||
updateControlsGeometry();
|
void Panel::chooseShareScreenSource() {
|
||||||
|
Ui::DesktopCapture::ChooseSource(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::chooseJoinAs() {
|
void Panel::chooseJoinAs() {
|
||||||
|
@ -1392,14 +1424,21 @@ void Panel::showMainMenu() {
|
||||||
if (_menu) {
|
if (_menu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto wide = (_mode.current() == PanelMode::Wide) && _wideMenu;
|
||||||
|
if (!wide && !_menuToggle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_menu.create(widget(), st::groupCallDropdownMenu);
|
_menu.create(widget(), st::groupCallDropdownMenu);
|
||||||
FillMenu(
|
FillMenu(
|
||||||
_menu.data(),
|
_menu.data(),
|
||||||
_peer,
|
_peer,
|
||||||
_call,
|
_call,
|
||||||
|
wide,
|
||||||
[=] { chooseJoinAs(); },
|
[=] { chooseJoinAs(); },
|
||||||
|
[=] { chooseShareScreenSource(); },
|
||||||
[=](auto box) { _layerBg->showBox(std::move(box)); });
|
[=](auto box) { _layerBg->showBox(std::move(box)); });
|
||||||
if (_menu->empty()) {
|
if (_menu->empty()) {
|
||||||
|
_wideMenuShown = false;
|
||||||
_menu.destroy();
|
_menu.destroy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1409,29 +1448,51 @@ void Panel::showMainMenu() {
|
||||||
raw->deleteLater();
|
raw->deleteLater();
|
||||||
if (_menu == raw) {
|
if (_menu == raw) {
|
||||||
_menu = nullptr;
|
_menu = nullptr;
|
||||||
_menuToggle->setForceRippled(false);
|
_wideMenuShown = false;
|
||||||
|
_trackControlsMenuLifetime.destroy();
|
||||||
|
if (_menuToggle) {
|
||||||
|
_menuToggle->setForceRippled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
raw->setShowStartCallback([=] {
|
raw->setShowStartCallback([=] {
|
||||||
if (_menu == raw) {
|
if (_menu == raw) {
|
||||||
_menuToggle->setForceRippled(true);
|
if (wide) {
|
||||||
|
_wideMenuShown = true;
|
||||||
|
} else if (_menuToggle) {
|
||||||
|
_menuToggle->setForceRippled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
raw->setHideStartCallback([=] {
|
raw->setHideStartCallback([=] {
|
||||||
if (_menu == raw) {
|
if (_menu == raw) {
|
||||||
_menuToggle->setForceRippled(false);
|
_wideMenuShown = false;
|
||||||
|
if (_menuToggle) {
|
||||||
|
_menuToggle->setForceRippled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_menuToggle->installEventFilter(_menu);
|
|
||||||
|
|
||||||
const auto x = st::groupCallMenuPosition.x();
|
if (wide) {
|
||||||
const auto y = st::groupCallMenuPosition.y();
|
_wideMenu->installEventFilter(_menu);
|
||||||
if (_menuToggle->x() > widget()->width() / 2) {
|
const auto x = st::groupCallWideMenuPosition.x();
|
||||||
_menu->moveToRight(x, y);
|
const auto y = st::groupCallWideMenuPosition.y();
|
||||||
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
_menu->moveToLeft(
|
||||||
|
_wideMenu->x() + x,
|
||||||
|
_wideMenu->y() - _menu->height() + y);
|
||||||
|
_menu->showAnimated(Ui::PanelAnimation::Origin::BottomLeft);
|
||||||
|
trackControl(_menu, _trackControlsMenuLifetime);
|
||||||
} else {
|
} else {
|
||||||
_menu->moveToLeft(x, y);
|
_menuToggle->installEventFilter(_menu);
|
||||||
_menu->showAnimated(Ui::PanelAnimation::Origin::TopLeft);
|
const auto x = st::groupCallMenuPosition.x();
|
||||||
|
const auto y = st::groupCallMenuPosition.y();
|
||||||
|
if (_menuToggle->x() > widget()->width() / 2) {
|
||||||
|
_menu->moveToRight(x, y);
|
||||||
|
_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
|
||||||
|
} else {
|
||||||
|
_menu->moveToLeft(x, y);
|
||||||
|
_menu->showAnimated(Ui::PanelAnimation::Origin::TopLeft);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1884,6 +1945,20 @@ void Panel::setupControlsBackgroundWide() {
|
||||||
trackControls(true);
|
trackControls(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename WidgetPointer>
|
||||||
|
void Panel::trackControl(WidgetPointer &widget, rpl::lifetime &lifetime) {
|
||||||
|
if (widget) {
|
||||||
|
widget->events(
|
||||||
|
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||||
|
if (e->type() == QEvent::Enter) {
|
||||||
|
toggleWideControls(true);
|
||||||
|
} else if (e->type() == QEvent::Leave) {
|
||||||
|
toggleWideControls(false);
|
||||||
|
}
|
||||||
|
}, lifetime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::trackControls(bool track) {
|
void Panel::trackControls(bool track) {
|
||||||
if (_trackControls == track) {
|
if (_trackControls == track) {
|
||||||
return;
|
return;
|
||||||
|
@ -1892,6 +1967,7 @@ void Panel::trackControls(bool track) {
|
||||||
if (!track) {
|
if (!track) {
|
||||||
_trackControlsLifetime.destroy();
|
_trackControlsLifetime.destroy();
|
||||||
_trackControlsOverStateLifetime.destroy();
|
_trackControlsOverStateLifetime.destroy();
|
||||||
|
_trackControlsMenuLifetime.destroy();
|
||||||
toggleWideControls(true);
|
toggleWideControls(true);
|
||||||
if (_wideControlsAnimation.animating()) {
|
if (_wideControlsAnimation.animating()) {
|
||||||
_wideControlsAnimation.stop();
|
_wideControlsAnimation.stop();
|
||||||
|
@ -1901,24 +1977,16 @@ void Panel::trackControls(bool track) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto trackOne = [=](auto &&widget) {
|
const auto trackOne = [=](auto &&widget) {
|
||||||
if (widget) {
|
trackControl(widget, _trackControlsOverStateLifetime);
|
||||||
const auto raw = &*widget;
|
|
||||||
raw->events(
|
|
||||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
|
||||||
if (e->type() == QEvent::Enter) {
|
|
||||||
toggleWideControls(true);
|
|
||||||
} else if (e->type() == QEvent::Leave) {
|
|
||||||
toggleWideControls(false);
|
|
||||||
}
|
|
||||||
}, _trackControlsOverStateLifetime);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
trackOne(_mute);
|
trackOne(_mute);
|
||||||
trackOne(_video);
|
trackOne(_video);
|
||||||
trackOne(_screenShare);
|
trackOne(_screenShare);
|
||||||
|
trackOne(_wideMenu);
|
||||||
trackOne(_settings);
|
trackOne(_settings);
|
||||||
trackOne(_hangup);
|
trackOne(_hangup);
|
||||||
trackOne(_controlsBackgroundWide);
|
trackOne(_controlsBackgroundWide);
|
||||||
|
trackControl(_menu, _trackControlsMenuLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateControlsGeometry() {
|
void Panel::updateControlsGeometry() {
|
||||||
|
@ -1956,28 +2024,21 @@ void Panel::updateButtonsGeometry() {
|
||||||
if (widget()->size().isEmpty() || (!_settings && !_callShare)) {
|
if (widget()->size().isEmpty() || (!_settings && !_callShare)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto toggle = [&](bool shown) {
|
const auto toggle = [](auto &widget, bool shown) {
|
||||||
const auto toggleOne = [&](auto &widget) {
|
if (widget && widget->isHidden() == shown) {
|
||||||
if (widget && widget->isHidden() == shown) {
|
widget->setVisible(shown);
|
||||||
widget->setVisible(shown);
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
toggleOne(_mute);
|
|
||||||
toggleOne(_video);
|
|
||||||
toggleOne(_screenShare);
|
|
||||||
toggleOne(_settings);
|
|
||||||
toggleOne(_callShare);
|
|
||||||
toggleOne(_hangup);
|
|
||||||
};
|
};
|
||||||
if (mode() == PanelMode::Wide) {
|
if (mode() == PanelMode::Wide) {
|
||||||
Assert(_video != nullptr);
|
Assert(_video != nullptr);
|
||||||
Assert(_screenShare != nullptr);
|
Assert(_screenShare != nullptr);
|
||||||
|
Assert(_wideMenu != nullptr);
|
||||||
Assert(_settings != nullptr);
|
Assert(_settings != nullptr);
|
||||||
Assert(_callShare == nullptr);
|
Assert(_callShare == nullptr);
|
||||||
|
|
||||||
const auto shown = _wideControlsAnimation.value(
|
const auto shown = _wideControlsAnimation.value(
|
||||||
_wideControlsShown ? 1. : 0.);
|
_wideControlsShown ? 1. : 0.);
|
||||||
toggle(shown > 0.);
|
const auto hidden = (shown == 0.);
|
||||||
|
|
||||||
if (_viewport) {
|
if (_viewport) {
|
||||||
_viewport->setControlsShown(shown);
|
_viewport->setControlsShown(shown);
|
||||||
|
@ -2002,17 +2063,23 @@ void Panel::updateButtonsGeometry() {
|
||||||
- membersWidth
|
- membersWidth
|
||||||
- membersSkip
|
- membersSkip
|
||||||
- fullWidth) / 2;
|
- fullWidth) / 2;
|
||||||
_screenShare->setVisible(true);
|
toggle(_screenShare, !hidden);
|
||||||
_screenShare->moveToLeft(left, buttonsTop);
|
_screenShare->moveToLeft(left, buttonsTop);
|
||||||
left += _screenShare->width() + skip;
|
left += _screenShare->width() + skip;
|
||||||
_screenShare->setVisible(true);
|
toggle(_video, !hidden);
|
||||||
_video->moveToLeft(left, buttonsTop);
|
_video->moveToLeft(left, buttonsTop);
|
||||||
left += _video->width() + skip;
|
left += _video->width() + skip;
|
||||||
|
toggle(_mute, !hidden);
|
||||||
_mute->moveInner({ left + addSkip, buttonsTop + addSkip });
|
_mute->moveInner({ left + addSkip, buttonsTop + addSkip });
|
||||||
left += muteSize + skip;
|
left += muteSize + skip;
|
||||||
_settings->setVisible(true);
|
const auto wideMenuShown = _call->canManage()
|
||||||
|
|| _call->showChooseJoinAs();
|
||||||
|
toggle(_settings, !hidden && !wideMenuShown);
|
||||||
|
toggle(_wideMenu, !hidden && wideMenuShown);
|
||||||
|
_wideMenu->moveToLeft(left, buttonsTop);
|
||||||
_settings->moveToLeft(left, buttonsTop);
|
_settings->moveToLeft(left, buttonsTop);
|
||||||
left += _settings->width() + skip;
|
left += _settings->width() + skip;
|
||||||
|
toggle(_hangup, !hidden);
|
||||||
_hangup->moveToLeft(left, buttonsTop);
|
_hangup->moveToLeft(left, buttonsTop);
|
||||||
left += _hangup->width();
|
left += _hangup->width();
|
||||||
if (_controlsBackgroundWide) {
|
if (_controlsBackgroundWide) {
|
||||||
|
@ -2025,8 +2092,6 @@ void Panel::updateButtonsGeometry() {
|
||||||
rect.marginsAdded(st::groupCallControlsBackMargin));
|
rect.marginsAdded(st::groupCallControlsBackMargin));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
toggle(true);
|
|
||||||
|
|
||||||
const auto muteTop = widget()->height()
|
const auto muteTop = widget()->height()
|
||||||
- st::groupCallMuteBottomSkip;
|
- st::groupCallMuteBottomSkip;
|
||||||
const auto buttonsTop = widget()->height()
|
const auto buttonsTop = widget()->height()
|
||||||
|
@ -2035,24 +2100,26 @@ void Panel::updateButtonsGeometry() {
|
||||||
const auto fullWidth = muteSize
|
const auto fullWidth = muteSize
|
||||||
+ 2 * (_settings ? _settings : _callShare)->width()
|
+ 2 * (_settings ? _settings : _callShare)->width()
|
||||||
+ 2 * st::groupCallButtonSkip;
|
+ 2 * st::groupCallButtonSkip;
|
||||||
|
toggle(_mute, true);
|
||||||
_mute->moveInner({ (widget()->width() - muteSize) / 2, muteTop });
|
_mute->moveInner({ (widget()->width() - muteSize) / 2, muteTop });
|
||||||
const auto leftButtonLeft = (widget()->width() - fullWidth) / 2;
|
const auto leftButtonLeft = (widget()->width() - fullWidth) / 2;
|
||||||
if (_screenShare) {
|
toggle(_screenShare, false);
|
||||||
_screenShare->setVisible(false);
|
toggle(_wideMenu, false);
|
||||||
}
|
toggle(_callShare, true);
|
||||||
if (_callShare) {
|
if (_callShare) {
|
||||||
_callShare->moveToLeft(leftButtonLeft, buttonsTop);
|
_callShare->moveToLeft(leftButtonLeft, buttonsTop);
|
||||||
}
|
}
|
||||||
const auto showVideoButton = videoButtonInNarrowMode();
|
const auto showVideoButton = videoButtonInNarrowMode();
|
||||||
|
toggle(_video, !_callShare && showVideoButton);
|
||||||
if (_video) {
|
if (_video) {
|
||||||
_video->setVisible(!_callShare && showVideoButton);
|
|
||||||
_video->setStyle(st::groupCallVideo, &st::groupCallVideoActive);
|
_video->setStyle(st::groupCallVideo, &st::groupCallVideoActive);
|
||||||
_video->moveToLeft(leftButtonLeft, buttonsTop);
|
_video->moveToLeft(leftButtonLeft, buttonsTop);
|
||||||
}
|
}
|
||||||
|
toggle(_settings, !_callShare && !showVideoButton);
|
||||||
if (_settings) {
|
if (_settings) {
|
||||||
_settings->setVisible(!_callShare && !showVideoButton);
|
|
||||||
_settings->moveToLeft(leftButtonLeft, buttonsTop);
|
_settings->moveToLeft(leftButtonLeft, buttonsTop);
|
||||||
}
|
}
|
||||||
|
toggle(_hangup, true);
|
||||||
_hangup->moveToRight(leftButtonLeft, buttonsTop);
|
_hangup->moveToRight(leftButtonLeft, buttonsTop);
|
||||||
}
|
}
|
||||||
if (_controlsBackgroundNarrow) {
|
if (_controlsBackgroundNarrow) {
|
||||||
|
|
|
@ -99,6 +99,9 @@ private:
|
||||||
void enlargeVideo();
|
void enlargeVideo();
|
||||||
void minimizeVideo();
|
void minimizeVideo();
|
||||||
|
|
||||||
|
template <typename WidgetPointer>
|
||||||
|
void trackControl(WidgetPointer &widget, rpl::lifetime &lifetime);
|
||||||
|
|
||||||
bool updateMode();
|
bool updateMode();
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
void updateButtonsGeometry();
|
void updateButtonsGeometry();
|
||||||
|
@ -111,6 +114,7 @@ private:
|
||||||
void refreshLeftButton();
|
void refreshLeftButton();
|
||||||
void refreshVideoButtons(
|
void refreshVideoButtons(
|
||||||
std::optional<bool> overrideWideMode = std::nullopt);
|
std::optional<bool> overrideWideMode = std::nullopt);
|
||||||
|
void refreshTopButton();
|
||||||
void toggleWideControls(bool shown);
|
void toggleWideControls(bool shown);
|
||||||
[[nodiscard]] bool videoButtonInNarrowMode() const;
|
[[nodiscard]] bool videoButtonInNarrowMode() const;
|
||||||
|
|
||||||
|
@ -118,6 +122,7 @@ private:
|
||||||
|
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void chooseJoinAs();
|
void chooseJoinAs();
|
||||||
|
void chooseShareScreenSource();
|
||||||
void addMembers();
|
void addMembers();
|
||||||
void kickParticipant(not_null<PeerData*> participantPeer);
|
void kickParticipant(not_null<PeerData*> participantPeer);
|
||||||
void kickParticipantSure(not_null<PeerData*> participantPeer);
|
void kickParticipantSure(not_null<PeerData*> participantPeer);
|
||||||
|
@ -154,11 +159,13 @@ private:
|
||||||
object_ptr<Ui::AbstractButton> _recordingMark = { nullptr };
|
object_ptr<Ui::AbstractButton> _recordingMark = { nullptr };
|
||||||
object_ptr<Ui::IconButton> _menuToggle = { nullptr };
|
object_ptr<Ui::IconButton> _menuToggle = { nullptr };
|
||||||
object_ptr<Ui::DropdownMenu> _menu = { nullptr };
|
object_ptr<Ui::DropdownMenu> _menu = { nullptr };
|
||||||
|
rpl::variable<bool> _wideMenuShown = false;
|
||||||
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
|
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
|
||||||
object_ptr<Members> _members = { nullptr };
|
object_ptr<Members> _members = { nullptr };
|
||||||
std::unique_ptr<Viewport> _viewport;
|
std::unique_ptr<Viewport> _viewport;
|
||||||
rpl::lifetime _trackControlsLifetime;
|
rpl::lifetime _trackControlsLifetime;
|
||||||
rpl::lifetime _trackControlsOverStateLifetime;
|
rpl::lifetime _trackControlsOverStateLifetime;
|
||||||
|
rpl::lifetime _trackControlsMenuLifetime;
|
||||||
object_ptr<Ui::FlatLabel> _startsIn = { nullptr };
|
object_ptr<Ui::FlatLabel> _startsIn = { nullptr };
|
||||||
object_ptr<Ui::RpWidget> _countdown = { nullptr };
|
object_ptr<Ui::RpWidget> _countdown = { nullptr };
|
||||||
std::shared_ptr<Ui::GroupCallScheduledLeft> _countdownData;
|
std::shared_ptr<Ui::GroupCallScheduledLeft> _countdownData;
|
||||||
|
@ -175,6 +182,7 @@ private:
|
||||||
object_ptr<Ui::RpWidget> _controlsBackgroundWide = { nullptr };
|
object_ptr<Ui::RpWidget> _controlsBackgroundWide = { nullptr };
|
||||||
std::unique_ptr<ControlsBackgroundNarrow> _controlsBackgroundNarrow;
|
std::unique_ptr<ControlsBackgroundNarrow> _controlsBackgroundNarrow;
|
||||||
object_ptr<Ui::CallButton> _settings = { nullptr };
|
object_ptr<Ui::CallButton> _settings = { nullptr };
|
||||||
|
object_ptr<Ui::CallButton> _wideMenu = { nullptr };
|
||||||
object_ptr<Ui::CallButton> _callShare = { nullptr };
|
object_ptr<Ui::CallButton> _callShare = { nullptr };
|
||||||
object_ptr<Ui::CallButton> _video = { nullptr };
|
object_ptr<Ui::CallButton> _video = { nullptr };
|
||||||
object_ptr<Ui::CallButton> _screenShare = { nullptr };
|
object_ptr<Ui::CallButton> _screenShare = { nullptr };
|
||||||
|
|
Loading…
Add table
Reference in a new issue