mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Improve narrow participants column design.
This commit is contained in:
parent
0dcc7a05f7
commit
00ce302b38
12 changed files with 271 additions and 116 deletions
|
@ -2069,8 +2069,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_context_remove_hand" = "Cancel request to speak";
|
||||
"lng_group_call_context_mute_for_me" = "Mute for me";
|
||||
"lng_group_call_context_unmute_for_me" = "Unmute for me";
|
||||
"lng_group_call_context_pin_video" = "Pin video";
|
||||
"lng_group_call_context_unpin_video" = "Unpin video";
|
||||
"lng_group_call_context_pin_camera" = "Pin video";
|
||||
"lng_group_call_context_unpin_camera" = "Unpin video";
|
||||
"lng_group_call_context_pin_screen" = "Pin screencast";
|
||||
"lng_group_call_context_unpin_screen" = "Unpin screencast";
|
||||
"lng_group_call_context_remove" = "Remove";
|
||||
"lng_group_call_remove_channel" = "Remove {channel} from the voice chat?";
|
||||
"lng_group_call_duration_days#one" = "{count} day";
|
||||
|
|
|
@ -811,9 +811,6 @@ groupCallHangupSmall: CallButton(groupCallHangup) {
|
|||
groupCallVideoSmallInner: IconButton(groupCallSettingsInner) {
|
||||
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
|
||||
iconPosition: point(-1px, 16px);
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: groupCallLeaveBgRipple;
|
||||
}
|
||||
height: 76px;
|
||||
}
|
||||
groupCallVideoSmall: CallButton(groupCallShareSmall) {
|
||||
|
@ -1136,6 +1133,19 @@ desktopCaptureSubmit: RoundButton(desktopCaptureCancel) {
|
|||
|
||||
groupCallNarrowSkip: 9px;
|
||||
groupCallNarrowRowSkip: 8px;
|
||||
groupCallNarrowSize: size(90px, 90px);
|
||||
groupCallNarrowSize: size(144px, 90px);
|
||||
groupCallWideModeWidthMin: 520px;
|
||||
groupCallWideModeSize: size(720px, 480px);
|
||||
groupCallNarrowAddMemberHeight: 32px;
|
||||
|
||||
groupCallNarrowAddMember: RoundButton(defaultActiveButton) {
|
||||
textFg: groupCallMemberNotJoinedStatus;
|
||||
textFgOver: groupCallMemberNotJoinedStatus;
|
||||
textBg: groupCallMembersBg;
|
||||
textBgOver: groupCallMembersBgOver;
|
||||
|
||||
height: 32px;
|
||||
radius: roundRadiusLarge;
|
||||
|
||||
ripple: groupCallRipple;
|
||||
}
|
||||
|
|
|
@ -388,6 +388,10 @@ GroupCall::GroupCall(
|
|||
, _joinHash(info.joinHash)
|
||||
, _id(inputCall.c_inputGroupCall().vid().v)
|
||||
, _scheduleDate(info.scheduleDate)
|
||||
, _cameraOutgoing(std::make_unique<Webrtc::VideoTrack>(
|
||||
Webrtc::VideoState::Inactive))
|
||||
, _screenOutgoing(std::make_unique<Webrtc::VideoTrack>(
|
||||
Webrtc::VideoState::Inactive))
|
||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||
, _checkJoinedTimer([=] { checkJoined(); })
|
||||
, _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
|
||||
|
@ -460,8 +464,15 @@ GroupCall::~GroupCall() {
|
|||
}
|
||||
|
||||
bool GroupCall::isSharingScreen() const {
|
||||
return _screenOutgoing
|
||||
&& (_screenOutgoing->state() == Webrtc::VideoState::Active);
|
||||
return (_screenOutgoing->state() == Webrtc::VideoState::Active);
|
||||
}
|
||||
|
||||
rpl::producer<bool> GroupCall::isSharingScreenValue() const {
|
||||
using namespace rpl::mappers;
|
||||
return _screenOutgoing->stateValue(
|
||||
) | rpl::map(
|
||||
_1 == Webrtc::VideoState::Active
|
||||
) | rpl::distinct_until_changed();
|
||||
}
|
||||
|
||||
const std::string &GroupCall::screenSharingEndpoint() const {
|
||||
|
@ -469,8 +480,15 @@ const std::string &GroupCall::screenSharingEndpoint() const {
|
|||
}
|
||||
|
||||
bool GroupCall::isSharingCamera() const {
|
||||
return _cameraOutgoing
|
||||
&& (_cameraOutgoing->state() == Webrtc::VideoState::Active);
|
||||
return (_cameraOutgoing->state() == Webrtc::VideoState::Active);
|
||||
}
|
||||
|
||||
rpl::producer<bool> GroupCall::isSharingCameraValue() const {
|
||||
using namespace rpl::mappers;
|
||||
return _cameraOutgoing->stateValue(
|
||||
) | rpl::map(
|
||||
_1 == Webrtc::VideoState::Active
|
||||
) | rpl::distinct_until_changed();
|
||||
}
|
||||
|
||||
const std::string &GroupCall::cameraSharingEndpoint() const {
|
||||
|
@ -611,7 +629,7 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
|
|||
const auto wasSounding = data.was && data.was->sounding;
|
||||
if (nowSpeaking == wasSpeaking && nowSounding == wasSounding) {
|
||||
return;
|
||||
} else if (!_videoEndpointPinned.empty()) {
|
||||
} else if (!_videoEndpointPinned.current().empty()) {
|
||||
return;
|
||||
}
|
||||
if (nowScreenEndpoint != newLarge
|
||||
|
@ -876,7 +894,7 @@ void GroupCall::setMyEndpointType(
|
|||
}
|
||||
const auto nowLarge = activeVideoEndpointType(
|
||||
_videoEndpointLarge.current());
|
||||
if (_videoEndpointPinned.empty()
|
||||
if (_videoEndpointPinned.current().empty()
|
||||
&& ((type == EndpointType::Screen
|
||||
&& nowLarge != EndpointType::Screen)
|
||||
|| (type == EndpointType::Camera
|
||||
|
@ -1604,14 +1622,10 @@ void GroupCall::setupMediaDevices() {
|
|||
void GroupCall::ensureOutgoingVideo() {
|
||||
Expects(_id != 0);
|
||||
|
||||
if (_cameraOutgoing) {
|
||||
if (_videoInited) {
|
||||
return;
|
||||
}
|
||||
|
||||
_cameraOutgoing = std::make_unique<Webrtc::VideoTrack>(
|
||||
Webrtc::VideoState::Inactive);
|
||||
_screenOutgoing = std::make_unique<Webrtc::VideoTrack>(
|
||||
Webrtc::VideoState::Inactive);
|
||||
_videoInited = true;
|
||||
|
||||
//static const auto hasDevices = [] {
|
||||
// return !Webrtc::GetVideoInputList().empty();
|
||||
|
@ -2057,7 +2071,7 @@ void GroupCall::setIncomingVideoEndpoints(
|
|||
feedOne(cameraSharingEndpoint());
|
||||
feedOne(screenSharingEndpoint());
|
||||
if (!newLarge.empty() && !newLargeFound) {
|
||||
newLarge = _videoEndpointPinned = std::string();
|
||||
_videoEndpointPinned = newLarge = std::string();
|
||||
}
|
||||
if (newLarge.empty()) {
|
||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||
|
@ -2105,7 +2119,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
|||
feedOne(cameraSharingEndpoint(), EndpointType::Camera);
|
||||
feedOne(screenSharingEndpoint(), EndpointType::Screen);
|
||||
if (!newLarge.empty() && !newLargeFound) {
|
||||
newLarge = _videoEndpointPinned = std::string();
|
||||
_videoEndpointPinned = newLarge = std::string();
|
||||
}
|
||||
if (newLarge.empty()) {
|
||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||
|
@ -2453,8 +2467,7 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) {
|
|||
MTP_bool(muted() != MuteState::Active),
|
||||
MTP_int(100000), // volume
|
||||
MTP_bool(muted() == MuteState::RaisedHand),
|
||||
MTP_bool(!_cameraOutgoing
|
||||
|| _cameraOutgoing->state() != Webrtc::VideoState::Active)
|
||||
MTP_bool(_cameraOutgoing->state() != Webrtc::VideoState::Active)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_updateMuteRequestId = 0;
|
||||
_peer->session().api().applyUpdates(result);
|
||||
|
@ -2472,7 +2485,9 @@ void GroupCall::pinVideoEndpoint(const std::string &endpoint) {
|
|||
if (endpoint.empty()) {
|
||||
_videoEndpointPinned = endpoint;
|
||||
} else if (streamsVideo(endpoint)) {
|
||||
_videoEndpointLarge = _videoEndpointPinned = endpoint;
|
||||
_videoEndpointPinned = std::string();
|
||||
_videoEndpointLarge = endpoint;
|
||||
_videoEndpointPinned = endpoint;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -235,10 +235,13 @@ public:
|
|||
&& activeVideoEndpointType(endpoint) != EndpointType::None;
|
||||
}
|
||||
[[nodiscard]] const std::string &videoEndpointPinned() const {
|
||||
return _videoEndpointPinned;
|
||||
return _videoEndpointPinned.current();
|
||||
}
|
||||
[[nodiscard]] rpl::producer<std::string> videoEndpointPinnedValue() const {
|
||||
return _videoEndpointPinned.value();
|
||||
}
|
||||
void pinVideoEndpoint(const std::string &endpoint);
|
||||
[[nodiscard]] std::string videoEndpointLarge() const {
|
||||
[[nodiscard]] const std::string &videoEndpointLarge() const {
|
||||
return _videoEndpointLarge.current();
|
||||
}
|
||||
[[nodiscard]] auto videoEndpointLargeValue() const
|
||||
|
@ -266,8 +269,10 @@ public:
|
|||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||
void setCurrentVideoDevice(const QString &deviceId);
|
||||
[[nodiscard]] bool isSharingScreen() const;
|
||||
[[nodiscard]] rpl::producer<bool> isSharingScreenValue() const;
|
||||
[[nodiscard]] const std::string &screenSharingEndpoint() const;
|
||||
[[nodiscard]] bool isSharingCamera() const;
|
||||
[[nodiscard]] rpl::producer<bool> isSharingCameraValue() const;
|
||||
[[nodiscard]] const std::string &cameraSharingEndpoint() const;
|
||||
[[nodiscard]] QString screenSharingDeviceId() const;
|
||||
void toggleVideo(bool active);
|
||||
|
@ -462,12 +467,14 @@ private:
|
|||
std::unique_ptr<Webrtc::VideoTrack> _screenOutgoing;
|
||||
QString _screenDeviceId;
|
||||
|
||||
bool _videoInited = false;
|
||||
|
||||
rpl::event_stream<LevelUpdate> _levelUpdates;
|
||||
rpl::event_stream<StreamsVideoUpdate> _streamsVideoUpdated;
|
||||
base::flat_set<std::string> _incomingVideoEndpoints;
|
||||
base::flat_map<std::string, EndpointType> _activeVideoEndpoints;
|
||||
rpl::variable<std::string> _videoEndpointLarge;
|
||||
std::string _videoEndpointPinned;
|
||||
rpl::variable<std::string> _videoEndpointPinned;
|
||||
std::unique_ptr<LargeTrack> _videoLargeTrackWrap;
|
||||
rpl::variable<Webrtc::VideoTrack*> _videoLargeTrack;
|
||||
base::flat_map<uint32, Data::LastSpokeTimes> _lastSpoke;
|
||||
|
|
|
@ -185,7 +185,8 @@ public:
|
|||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode,
|
||||
bool selected = false);
|
||||
|
||||
|
@ -256,19 +257,32 @@ private:
|
|||
void ensureUserpicCache(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
int size);
|
||||
bool paintVideo(Painter &p, int x, int y, int size, PanelMode mode);
|
||||
bool paintVideo(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode);
|
||||
[[nodiscard]] static std::tuple<int, int, int> UserpicInWideMode(
|
||||
int x,
|
||||
int y,
|
||||
int size);
|
||||
void paintBlobs(Painter &p, int x, int y, int size, PanelMode mode);
|
||||
int sizew,
|
||||
int sizeh);
|
||||
void paintBlobs(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int sizew,
|
||||
int sizeh, PanelMode mode);
|
||||
void paintScaledUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode);
|
||||
|
||||
const not_null<RowDelegate*> _delegate;
|
||||
|
@ -694,7 +708,13 @@ void Row::ensureUserpicCache(
|
|||
}
|
||||
}
|
||||
|
||||
bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
||||
bool Row::paintVideo(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode) {
|
||||
if (!_videoTrackShown) {
|
||||
return false;
|
||||
}
|
||||
|
@ -706,12 +726,14 @@ bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
|||
|| _videoTrackShown->state() != Webrtc::VideoState::Active) {
|
||||
return false;
|
||||
}
|
||||
const auto resize = (videoSize.width() > videoSize.height())
|
||||
? QSize(videoSize.width() * size / videoSize.height(), size)
|
||||
: QSize(size, videoSize.height() * size / videoSize.width());
|
||||
const auto videow = videoSize.width();
|
||||
const auto videoh = videoSize.height();
|
||||
const auto resize = (videow * sizeh > videoh * sizew)
|
||||
? QSize(videow * sizeh / videoh, sizeh)
|
||||
: QSize(sizew, videoh * sizew / videow);
|
||||
const auto request = Webrtc::FrameRequest{
|
||||
.resize = resize * cIntRetinaFactor(),
|
||||
.outer = QSize(size, size) * cIntRetinaFactor(),
|
||||
.outer = QSize(sizew, sizeh) * cIntRetinaFactor(),
|
||||
};
|
||||
const auto frame = _videoTrackShown->frame(request);
|
||||
auto copy = frame; // #TODO calls optimize.
|
||||
|
@ -727,18 +749,30 @@ bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::tuple<int, int, int> Row::UserpicInWideMode(int x, int y, int size) {
|
||||
std::tuple<int, int, int> Row::UserpicInWideMode(
|
||||
int x,
|
||||
int y,
|
||||
int sizew,
|
||||
int sizeh) {
|
||||
const auto useSize = st::groupCallMembersList.item.photoSize;
|
||||
const auto skip = (size - useSize) / 2;
|
||||
return { x + skip, y + skip, useSize };
|
||||
const auto skipx = (sizew - useSize) / 2;
|
||||
const auto skipy = (sizeh - useSize) / 2;
|
||||
return { x + skipx, y + skipy, useSize };
|
||||
}
|
||||
|
||||
void Row::paintBlobs(Painter &p, int x, int y, int size, PanelMode mode) {
|
||||
void Row::paintBlobs(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode) {
|
||||
if (!_blobsAnimation) {
|
||||
return;
|
||||
}
|
||||
auto size = sizew;
|
||||
if (mode == PanelMode::Wide) {
|
||||
std::tie(x, y, size) = UserpicInWideMode(x, y, size);
|
||||
std::tie(x, y, size) = UserpicInWideMode(x, y, sizew, sizeh);
|
||||
}
|
||||
const auto mutedByMe = (_state == State::MutedByMe);
|
||||
const auto shift = QPointF(x + size / 2., y + size / 2.);
|
||||
|
@ -761,10 +795,12 @@ void Row::paintScaledUserpic(
|
|||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode) {
|
||||
auto size = sizew;
|
||||
if (mode == PanelMode::Wide) {
|
||||
std::tie(x, y, size) = UserpicInWideMode(x, y, size);
|
||||
std::tie(x, y, size) = UserpicInWideMode(x, y, sizew, sizeh);
|
||||
}
|
||||
if (!_blobsAnimation) {
|
||||
peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
|
||||
|
@ -800,7 +836,8 @@ void Row::paintScaledUserpic(
|
|||
|
||||
auto Row::generatePaintUserpicCallback() -> PaintRoundImageCallback {
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
||||
paintComplexUserpic(p, x, y, outerWidth, size, PanelMode::Default);
|
||||
const auto outer = outerWidth;
|
||||
paintComplexUserpic(p, x, y, outer, size, size, PanelMode::Default);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -809,18 +846,20 @@ void Row::paintComplexUserpic(
|
|||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
int sizew,
|
||||
int sizeh,
|
||||
PanelMode mode,
|
||||
bool selected) {
|
||||
if (mode == PanelMode::Wide) {
|
||||
if (paintVideo(p, x, y, size, mode)) {
|
||||
if (paintVideo(p, x, y, sizew, sizeh, mode)) {
|
||||
return;
|
||||
}
|
||||
_delegate->rowPaintWideBackground(p, selected);
|
||||
paintRipple(p, x, y, outerWidth);
|
||||
}
|
||||
paintBlobs(p, x, y, size, mode);
|
||||
if (mode == PanelMode::Default && paintVideo(p, x, y, size, mode)) {
|
||||
paintBlobs(p, x, y, sizew, sizeh, mode);
|
||||
if (mode == PanelMode::Default
|
||||
&& paintVideo(p, x, y, sizew, sizeh, mode)) {
|
||||
return;
|
||||
}
|
||||
paintScaledUserpic(
|
||||
|
@ -829,7 +868,8 @@ void Row::paintComplexUserpic(
|
|||
x,
|
||||
y,
|
||||
outerWidth,
|
||||
size,
|
||||
sizew,
|
||||
sizeh,
|
||||
mode);
|
||||
}
|
||||
|
||||
|
@ -1826,7 +1866,7 @@ void MembersController::rowPaintIcon(
|
|||
void MembersController::rowPaintWideBackground(Painter &p, bool selected) {
|
||||
(selected ? _wideRoundRectSelected : _wideRoundRect).paint(
|
||||
p,
|
||||
{ QPoint(), st::groupCallNarrowSize });
|
||||
{ QPoint(st::groupCallNarrowSkip, 0), st::groupCallNarrowSize });
|
||||
}
|
||||
|
||||
int MembersController::customRowHeight() {
|
||||
|
@ -1840,12 +1880,14 @@ void MembersController::customRowPaint(
|
|||
bool selected) {
|
||||
const auto real = static_cast<Row*>(row.get());
|
||||
const auto width = st::groupCallNarrowSize.width();
|
||||
const auto height = st::groupCallNarrowSize.height();
|
||||
real->paintComplexUserpic(
|
||||
p,
|
||||
0,
|
||||
st::groupCallNarrowSkip,
|
||||
0,
|
||||
width,
|
||||
width,
|
||||
height,
|
||||
PanelMode::Wide,
|
||||
selected);
|
||||
}
|
||||
|
@ -1854,7 +1896,9 @@ bool MembersController::customRowSelectionPoint(
|
|||
not_null<PeerListRow*> row,
|
||||
int x,
|
||||
int y) {
|
||||
return y < st::groupCallNarrowSize.height();
|
||||
return x >= st::groupCallNarrowSkip
|
||||
&& x < st::groupCallNarrowSkip + st::groupCallNarrowSize.width()
|
||||
&& y < st::groupCallNarrowSize.height();
|
||||
}
|
||||
|
||||
Fn<QImage()> MembersController::customRowRippleMaskGenerator() {
|
||||
|
@ -1973,7 +2017,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|
|||
const auto participant = real->participantByEndpoint(pinnedEndpoint);
|
||||
if (participant && participant->peer == participantPeer) {
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_unpin_video(tr::now),
|
||||
tr::lng_group_call_context_unpin_camera(tr::now),
|
||||
[=] { _call->pinVideoEndpoint(std::string()); });
|
||||
} else {
|
||||
const auto &participants = real->participants();
|
||||
|
@ -1992,7 +2036,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|
|||
: camera);
|
||||
};
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_pin_video(tr::now),
|
||||
tr::lng_group_call_context_pin_camera(tr::now),
|
||||
callback);
|
||||
}
|
||||
}
|
||||
|
@ -2292,27 +2336,61 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
|||
});
|
||||
}
|
||||
|
||||
_canAddMembers.value(
|
||||
) | rpl::start_with_next([=](bool can) {
|
||||
rpl::combine(
|
||||
_canAddMembers.value(),
|
||||
_mode.value()
|
||||
) | rpl::start_with_next([=](bool can, PanelMode mode) {
|
||||
const auto old = _addMemberButton.current();
|
||||
delete old;
|
||||
if (!can) {
|
||||
delete _addMemberButton.current();
|
||||
_addMemberButton = nullptr;
|
||||
updateControlsGeometry();
|
||||
return;
|
||||
} else if (_addMemberButton.current()) {
|
||||
if (old) {
|
||||
_addMemberButton = nullptr;
|
||||
updateControlsGeometry();
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto addMember = Settings::CreateButton(
|
||||
this,
|
||||
tr::lng_group_call_invite(),
|
||||
st::groupCallAddMember,
|
||||
&st::groupCallAddMemberIcon,
|
||||
st::groupCallAddMemberIconLeft);
|
||||
auto addMember = (Ui::AbstractButton*)nullptr;
|
||||
auto wrap = [&]() -> object_ptr<Ui::RpWidget> {
|
||||
if (mode == PanelMode::Default) {
|
||||
auto result = Settings::CreateButton(
|
||||
this,
|
||||
tr::lng_group_call_invite(),
|
||||
st::groupCallAddMember,
|
||||
&st::groupCallAddMemberIcon,
|
||||
st::groupCallAddMemberIconLeft,
|
||||
&st::groupCallMemberInactiveIcon);
|
||||
addMember = result.data();
|
||||
return result;
|
||||
}
|
||||
auto result = object_ptr<Ui::RpWidget>(_layout.get());
|
||||
const auto skip = st::groupCallNarrowSkip;
|
||||
const auto fullwidth = st::groupCallNarrowSize.width()
|
||||
+ 2 * skip;
|
||||
const auto fullheight = st::groupCallNarrowAddMember.height
|
||||
+ st::groupCallNarrowRowSkip;
|
||||
result->resize(fullwidth, fullheight);
|
||||
const auto button = Ui::CreateChild<Ui::RoundButton>(
|
||||
result.data(),
|
||||
rpl::single(QString()),
|
||||
st::groupCallNarrowAddMember);
|
||||
button->move(skip, 0);
|
||||
const auto width = fullwidth - 2 * skip;
|
||||
button->setFullWidth(width);
|
||||
Settings::AddButtonIcon(
|
||||
button,
|
||||
&st::groupCallAddMemberIcon,
|
||||
(width - st::groupCallAddMemberIcon.width()) / 2,
|
||||
&st::groupCallMemberInactiveIcon);
|
||||
addMember = button;
|
||||
return result;
|
||||
}();
|
||||
addMember->show();
|
||||
addMember->addClickHandler([=] { // TODO throttle(ripple duration)
|
||||
_addMemberRequests.fire({});
|
||||
});
|
||||
_addMemberButton = _layout->insert(1, std::move(addMember));
|
||||
addMember->clicks(
|
||||
) | rpl::to_empty | rpl::start_to_stream(
|
||||
_addMemberRequests,
|
||||
addMember->lifetime());
|
||||
_addMemberButton = wrap.data();
|
||||
_layout->insert(1, std::move(wrap));
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ private:
|
|||
std::unique_ptr<PeerListController> _listController;
|
||||
not_null<Ui::VerticalLayout*> _layout;
|
||||
const not_null<Ui::RpWidget*> _pinnedVideo;
|
||||
rpl::variable<Ui::SettingsButton*> _addMemberButton = nullptr;
|
||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||
ListWidget *_list = nullptr;
|
||||
rpl::event_stream<> _addMemberRequests;
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ constexpr auto kRecordingAnimationDuration = crl::time(1200);
|
|||
constexpr auto kRecordingOpacity = 0.6;
|
||||
constexpr auto kStartNoConfirmation = TimeId(10);
|
||||
constexpr auto kControlsBackgroundOpacity = 0.8;
|
||||
constexpr auto kOverrideActiveColorBgAlpha = 236;
|
||||
|
||||
class InviteController final : public ParticipantsBoxController {
|
||||
public:
|
||||
|
@ -713,8 +714,21 @@ void Panel::refreshLeftButton() {
|
|||
}
|
||||
const auto raw = _callShare ? _callShare.data() : _settings.data();
|
||||
raw->show();
|
||||
raw->setColorOverrides(_mute->colorOverrides());
|
||||
|
||||
auto overrides = _mute->colorOverrides();
|
||||
raw->setColorOverrides(rpl::duplicate(overrides));
|
||||
|
||||
auto toggleableOverrides = [&](rpl::producer<bool> active) {
|
||||
return rpl::combine(
|
||||
std::move(active),
|
||||
rpl::duplicate(overrides)
|
||||
) | rpl::map([](bool active, Ui::CallButtonColors colors) {
|
||||
if (active && colors.bg) {
|
||||
colors.bg->setAlpha(kOverrideActiveColorBgAlpha);
|
||||
}
|
||||
return colors;
|
||||
});
|
||||
};
|
||||
if (!_video) {
|
||||
_video.create(
|
||||
widget(),
|
||||
|
@ -725,7 +739,12 @@ void Panel::refreshLeftButton() {
|
|||
_call->toggleVideo(!_call->isSharingCamera());
|
||||
});
|
||||
_video->setText(tr::lng_group_call_video());
|
||||
_video->setColorOverrides(_mute->colorOverrides());
|
||||
_video->setColorOverrides(
|
||||
toggleableOverrides(_call->isSharingCameraValue()));
|
||||
_call->isSharingCameraValue(
|
||||
) | rpl::start_with_next([=](bool sharing) {
|
||||
_video->setProgress(sharing ? 1. : 0.);
|
||||
}, _video->lifetime());
|
||||
}
|
||||
if (!_screenShare) {
|
||||
_screenShare.create(widget(), st::groupCallScreenShareSmall);
|
||||
|
@ -736,7 +755,12 @@ void Panel::refreshLeftButton() {
|
|||
#endif // Q_OS_LINUX
|
||||
});
|
||||
_screenShare->setText(tr::lng_group_call_screen_share());
|
||||
_screenShare->setColorOverrides(_mute->colorOverrides());
|
||||
_screenShare->setColorOverrides(
|
||||
toggleableOverrides(_call->isSharingScreenValue()));
|
||||
_call->isSharingScreenValue(
|
||||
) | rpl::start_with_next([=](bool sharing) {
|
||||
_screenShare->setProgress(sharing ? 1. : 0.);
|
||||
}, _screenShare->lifetime());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1687,19 +1711,19 @@ void Panel::updateMembersGeometry() {
|
|||
}
|
||||
const auto desiredHeight = _members->desiredHeight();
|
||||
if (_mode == PanelMode::Wide) {
|
||||
const auto skip = st::groupCallNarrowSkip;
|
||||
const auto membersWidth = st::groupCallNarrowSize.width() + 2 * skip;
|
||||
const auto top = st::groupCallWideVideoTop;
|
||||
_members->setGeometry(
|
||||
st::groupCallNarrowSkip,
|
||||
0,
|
||||
st::groupCallNarrowSize.width(),
|
||||
top,
|
||||
membersWidth,
|
||||
std::min(desiredHeight, widget()->height()));
|
||||
const auto pinnedLeft = st::groupCallNarrowSkip * 2
|
||||
+ st::groupCallNarrowSize.width();
|
||||
const auto pinnedTop = st::groupCallWideVideoTop;
|
||||
_pinnedVideo->setGeometry(
|
||||
pinnedLeft,
|
||||
pinnedTop,
|
||||
widget()->width() - pinnedLeft - st::groupCallNarrowSkip,
|
||||
widget()->height() - pinnedTop - st::groupCallNarrowSkip);
|
||||
membersWidth,
|
||||
top,
|
||||
widget()->width() - membersWidth - skip,
|
||||
widget()->height() - top - skip);
|
||||
} else {
|
||||
const auto membersBottom = _videoMode.current()
|
||||
? (widget()->height() - st::groupCallMembersBottomSkipSmall)
|
||||
|
|
|
@ -35,9 +35,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Settings {
|
||||
|
||||
object_ptr<Section> CreateSection(
|
||||
Type type,
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::SessionController*> controller) {
|
||||
Type type,
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::SessionController*> controller) {
|
||||
switch (type) {
|
||||
case Type::Main:
|
||||
return object_ptr<Main>(parent, controller);
|
||||
|
@ -74,8 +74,8 @@ void AddDivider(not_null<Ui::VerticalLayout*> container) {
|
|||
}
|
||||
|
||||
void AddDividerText(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text) {
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text) {
|
||||
container->add(object_ptr<Ui::DividerLabel>(
|
||||
container,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
|
@ -85,37 +85,49 @@ void AddDividerText(
|
|||
st::settingsDividerLabelPadding));
|
||||
}
|
||||
|
||||
not_null<Ui::RpWidget*> AddButtonIcon(
|
||||
not_null<Ui::AbstractButton*> button,
|
||||
const style::icon *leftIcon,
|
||||
int iconLeft,
|
||||
const style::color *leftIconOver) {
|
||||
const auto icon = Ui::CreateChild<Ui::RpWidget>(button.get());
|
||||
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
icon->resize(leftIcon->size());
|
||||
button->sizeValue(
|
||||
) | rpl::start_with_next([=](QSize size) {
|
||||
icon->moveToLeft(
|
||||
iconLeft ? iconLeft : st::settingsSectionIconLeft,
|
||||
(size.height() - icon->height()) / 2,
|
||||
size.width());
|
||||
}, icon->lifetime());
|
||||
icon->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
Painter p(icon);
|
||||
const auto width = icon->width();
|
||||
const auto paintOver = (button->isOver() || button->isDown())
|
||||
&& !button->isDisabled();
|
||||
if (!paintOver) {
|
||||
leftIcon->paint(p, QPoint(), width);
|
||||
} else if (leftIconOver) {
|
||||
leftIcon->paint(p, QPoint(), width, (*leftIconOver)->c);
|
||||
} else {
|
||||
leftIcon->paint(p, QPoint(), width, st::menuIconFgOver->c);
|
||||
}
|
||||
}, icon->lifetime());
|
||||
return icon;
|
||||
}
|
||||
|
||||
object_ptr<Button> CreateButton(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QString> text,
|
||||
const style::SettingsButton &st,
|
||||
const style::icon *leftIcon,
|
||||
int iconLeft) {
|
||||
int iconLeft,
|
||||
const style::color *leftIconOver) {
|
||||
auto result = object_ptr<Button>(parent, std::move(text), st);
|
||||
const auto button = result.data();
|
||||
if (leftIcon) {
|
||||
const auto icon = Ui::CreateChild<Ui::RpWidget>(button);
|
||||
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
icon->resize(leftIcon->size());
|
||||
button->sizeValue(
|
||||
) | rpl::start_with_next([=](QSize size) {
|
||||
icon->moveToLeft(
|
||||
iconLeft ? iconLeft : st::settingsSectionIconLeft,
|
||||
(size.height() - icon->height()) / 2,
|
||||
size.width());
|
||||
}, icon->lifetime());
|
||||
icon->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
Painter p(icon);
|
||||
const auto width = icon->width();
|
||||
const auto paintOver = (button->isOver() || button->isDown())
|
||||
&& !button->isDisabled();
|
||||
if (paintOver) {
|
||||
leftIcon->paint(p, QPoint(), width, st::menuIconFgOver->c);
|
||||
} else {
|
||||
leftIcon->paint(p, QPoint(), width);
|
||||
}
|
||||
}, icon->lifetime());
|
||||
AddButtonIcon(button, leftIcon, iconLeft, leftIconOver);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Ui {
|
|||
class VerticalLayout;
|
||||
class FlatLabel;
|
||||
class SettingsButton;
|
||||
class AbstractButton;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -70,12 +71,18 @@ void AddDivider(not_null<Ui::VerticalLayout*> container);
|
|||
void AddDividerText(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text);
|
||||
not_null<Ui::RpWidget*> AddButtonIcon(
|
||||
not_null<Ui::AbstractButton*> button,
|
||||
const style::icon *leftIcon,
|
||||
int iconLeft,
|
||||
const style::color *leftIconOver);
|
||||
object_ptr<Button> CreateButton(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QString> text,
|
||||
const style::SettingsButton &st,
|
||||
const style::icon *leftIcon = nullptr,
|
||||
int iconLeft = 0);
|
||||
int iconLeft = 0,
|
||||
const style::color *leftIconOver = nullptr);
|
||||
not_null<Button*> AddButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text,
|
||||
|
|
2
Telegram/ThirdParty/tgcalls
vendored
2
Telegram/ThirdParty/tgcalls
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 6ee9e983b8eebceb2603633c12d4cf2b973be046
|
||||
Subproject commit 5c950149f53f109dbac37bde8b1144234e7c3c9a
|
|
@ -1 +1 @@
|
|||
Subproject commit e1b96399d9031c4ef0354631e6bb375029d29d9f
|
||||
Subproject commit df721be3fa14a27dfc230d2e3c42bb1a7c9d0617
|
|
@ -1 +1 @@
|
|||
Subproject commit 3c1866f52d88f9430341f9a9f1ed3dbbb3b794ea
|
||||
Subproject commit b0c5d9220bb8f0fc614712167c8276504e60b224
|
Loading…
Add table
Reference in a new issue