Toggle video pin from LargeVideo.

This commit is contained in:
John Preston 2021-05-11 12:57:41 +04:00
parent 9f41461209
commit 7e8d1f7974
6 changed files with 95 additions and 22 deletions

View file

@ -1173,7 +1173,7 @@ groupCallVideoCrossLine: CrossLineAnimation(groupCallNarrowInactiveCrossLine) {
}
groupCallLargeVideoCrossLine: CrossLineAnimation(groupCallMemberColoredCrossLine) {
fg: groupCallVideoTextFg;
fg: groupCallVideoSubTextFg;
icon: icon {{ "calls/group_calls_unmuted", groupCallVideoSubTextFg }};
}
@ -1187,7 +1187,7 @@ GroupCallLargeVideo {
}
groupCallLargeVideoWide: GroupCallLargeVideo {
shadowHeight: 60px;
shadowHeight: 100px;
controlsAlign: align(top);
namePosition: point(15px, 8px);
statusPosition: point(15px, 28px);
@ -1195,7 +1195,7 @@ groupCallLargeVideoWide: GroupCallLargeVideo {
iconPosition: point(14px, 15px);
}
groupCallLargeVideoNarrow: GroupCallLargeVideo {
shadowHeight: 50px;
shadowHeight: 80px;
controlsAlign: align(top);
namePosition: point(64px, 44px);
statusPosition: point(64px, 20px);

View file

@ -28,7 +28,9 @@ LargeVideo::LargeVideo(
rpl::producer<bool> pinned)
: _content(parent, [=](QRect clip) { paint(clip); })
, _st(st)
, _pin(st::groupCallLargeVideoPin) {
, _pin(st::groupCallLargeVideoPin)
, _pinButton(&_content)
, _topControls(_st.controlsAlign == style::al_top) {
_content.setVisible(visible);
setup(std::move(track), std::move(pinned));
}
@ -45,16 +47,15 @@ void LargeVideo::setGeometry(int x, int y, int width, int height) {
_content.setGeometry(x, y, width, height);
}
rpl::producer<bool> LargeVideo::pinToggled() const {
return _pinButton.clicks() | rpl::map([=] { return !_pinned; });
}
void LargeVideo::setup(
rpl::producer<LargeVideoTrack> track,
rpl::producer<bool> pinned) {
_content.setAttribute(Qt::WA_OpaquePaintEvent);
std::move(pinned) | rpl::start_with_next([=](bool pinned) {
_pinned = pinned;
_content.update();
}, _content.lifetime());
rpl::combine(
_content.shownValue(),
std::move(track)
@ -78,6 +79,45 @@ void LargeVideo::setup(
_content.update();
}, _trackLifetime);
}, _content.lifetime());
setupControls(std::move(pinned));
}
void LargeVideo::setupControls(rpl::producer<bool> pinned) {
std::move(pinned) | rpl::start_with_next([=](bool pinned) {
_pinned = pinned;
_content.update();
}, _content.lifetime());
_content.sizeValue(
) | rpl::start_with_next([=](QSize size) {
updateControlsGeometry();
}, _content.lifetime());
}
void LargeVideo::updateControlsGeometry() {
if (_topControls) {
const auto &pin = st::groupCallLargeVideoPin.icon;
const auto pinWidth = pin.width();
const auto pinRight = (_content.width() - _st.pinPosition.x());
const auto pinTop = _st.pinPosition.y();
const auto &icon = st::groupCallLargeVideoCrossLine.icon;
const auto iconLeft = _content.width()
- _st.iconPosition.x()
- icon.width();
const auto skip = iconLeft - pinRight;
_pinButton.setGeometry(
pinRight - pin.width() - (skip / 2),
0,
pin.width() + skip,
pinTop * 2 + pin.height());
} else {
_pinButton.setGeometry(
0,
_content.height() - _st.namePosition.y(),
_st.namePosition.x(),
_st.namePosition.y());
}
}
void LargeVideo::paint(QRect clip) {
@ -139,12 +179,17 @@ void LargeVideo::paint(QRect clip) {
}
void LargeVideo::paintControls(Painter &p, QRect clip) {
const auto shown = _controlsAnimation.value(_controlsShown ? 1. : 0.);
if (shown == 0.) {
return;
}
const auto width = _content.width();
const auto height = _content.height();
const auto topControls = (_st.controlsAlign == style::al_top);
// Shadow.
if (_shadow.isNull()) {
if (topControls) {
if (_topControls) {
_shadow = GenerateShadow(_st.shadowHeight, kShadowMaxAlpha, 0);
} else {
_shadow = GenerateShadow(_st.shadowHeight, 0, kShadowMaxAlpha);
@ -152,7 +197,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
}
const auto shadowRect = QRect(
0,
topControls ? 0 : (height - _st.shadowHeight),
_topControls ? 0 : (height - _st.shadowHeight),
width,
_st.shadowHeight);
const auto shadowFill = shadowRect.intersected(clip);
@ -170,21 +215,23 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
shadowFill.height() * factor));
_track.row->lazyInitialize(st::groupCallMembersListItem);
p.setPen(topControls
// Name.
p.setPen(_topControls
? st::groupCallVideoTextFg
: st::groupCallVideoSubTextFg);
const auto hasWidth = width
- (topControls ? _st.pinPosition.x() : _st.iconPosition.x())
- (_topControls ? _st.pinPosition.x() : _st.iconPosition.x())
- _st.namePosition.x();
const auto nameLeft = _st.namePosition.x();
const auto nameTop = topControls
const auto nameTop = _topControls
? _st.namePosition.y()
: (height - _st.namePosition.y());
_track.row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width);
// Status.
p.setPen(st::groupCallVideoSubTextFg);
const auto statusLeft = _st.statusPosition.x();
const auto statusTop = topControls
const auto statusTop = _topControls
? _st.statusPosition.y()
: (height - _st.statusPosition.y());
_track.row->paintComplexStatusText(
@ -197,9 +244,10 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
false,
MembersRowStyle::LargeVideo);
// Mute.
const auto &icon = st::groupCallLargeVideoCrossLine.icon;
const auto iconLeft = width - _st.iconPosition.x() - icon.width();
const auto iconTop = topControls
const auto iconTop = _topControls
? _st.iconPosition.y()
: (height - _st.iconPosition.y());
_track.row->paintMuteIcon(
@ -207,11 +255,12 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
{ iconLeft, iconTop, icon.width(), icon.height() },
MembersRowStyle::LargeVideo);
// Pin.
const auto pinWidth = st::groupCallLargeVideoPin.icon.width();
const auto pinLeft = topControls
const auto pinLeft = _topControls
? (width - _st.pinPosition.x() - pinWidth)
: _st.pinPosition.x();
const auto pinTop = topControls
const auto pinTop = _topControls
? _st.pinPosition.y()
: (height - _st.pinPosition.y());
_pin.paint(p, pinLeft, pinTop, _pinned ? 1. : 0.);

View file

@ -8,7 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "ui/rp_widget.h"
#include "ui/abstract_button.h"
#include "ui/effects/cross_line.h"
#include "ui/effects/animations.h"
#if defined Q_OS_MAC
#define USE_OPENGL_LARGE_VIDEO
@ -60,6 +62,12 @@ public:
void setVisible(bool visible);
void setGeometry(int x, int y, int width, int height);
[[nodiscard]] rpl::producer<bool> pinToggled() const;
[[nodiscard]] rpl::lifetime &lifetime() {
return _content.lifetime();
}
private:
#ifdef USE_OPENGL_LARGE_VIDEO
using ContentParent = Ui::RpWidgetWrap<QOpenGLWidget>;
@ -86,15 +94,21 @@ private:
void setup(
rpl::producer<LargeVideoTrack> track,
rpl::producer<bool> pinned);
void setupControls(rpl::producer<bool> pinned);
void paint(QRect clip);
void paintControls(Painter &p, QRect clip);
void updateControlsGeometry();
Content _content;
const style::GroupCallLargeVideo &_st;
LargeVideoTrack _track;
QImage _shadow;
Ui::CrossLineAnimation _pin;
Ui::AbstractButton _pinButton;
Ui::Animations::Simple _controlsAnimation;
bool _topControls = false;
bool _pinned = false;
bool _controlsShown = true;
rpl::lifetime _trackLifetime;
};

View file

@ -727,7 +727,9 @@ void MembersRow::paintComplexStatusText(
bool selected,
MembersRowStyle style) {
const auto &font = st::normalFont;
const auto about = (_state == State::Inactive
const auto about = (style == MembersRowStyle::LargeVideo)
? QString()
: (_state == State::Inactive
|| _state == State::Muted
|| (_state == State::RaisedHand && !_raisedHandStatus))
? _aboutText
@ -767,7 +769,7 @@ void MembersRow::paintComplexStatusText(
outerWidth,
(_state == State::MutedByMe
? tr::lng_group_call_muted_by_me_status(tr::now)
: (!about.isEmpty() && style != MembersRowStyle::LargeVideo)
: !about.isEmpty()
? font->m.elidedText(about, Qt::ElideRight, availableWidth)
: _delegate->rowIsMe(peer())
? tr::lng_status_connecting(tr::now)

View file

@ -1008,6 +1008,14 @@ void Panel::setupPinnedVideo() {
visible,
std::move(track),
_call->videoEndpointPinnedValue());
_pinnedVideo->pinToggled(
) | rpl::start_with_next([=](bool pinned) {
if (!pinned) {
_call->pinVideoEndpoint(VideoEndpoint{});
} else if (const auto &large = _call->videoEndpointLarge()) {
_call->pinVideoEndpoint(large);
}
}, _pinnedVideo->lifetime());
raiseControls();
}

@ -1 +1 @@
Subproject commit 2b36c36dcbe49fa0d62543b45f42f820cb0c22ad
Subproject commit aeeb13bd029597da8cf5104c2e7c56f4641cd6b6