mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 15:43:55 +02:00
Use LargeVideo in the default mode.
This commit is contained in:
parent
5f4903a279
commit
0db0abe608
5 changed files with 58 additions and 105 deletions
|
@ -1191,14 +1191,14 @@ groupCallLargeVideoWide: GroupCallLargeVideo {
|
||||||
controlsAlign: align(top);
|
controlsAlign: align(top);
|
||||||
namePosition: point(15px, 8px);
|
namePosition: point(15px, 8px);
|
||||||
statusPosition: point(15px, 28px);
|
statusPosition: point(15px, 28px);
|
||||||
pinPosition: point(52px, 15px);
|
pinPosition: point(52px, 16px);
|
||||||
iconPosition: point(14px, 15px);
|
iconPosition: point(14px, 16px);
|
||||||
}
|
}
|
||||||
groupCallLargeVideoNarrow: GroupCallLargeVideo {
|
groupCallLargeVideoNarrow: GroupCallLargeVideo {
|
||||||
shadowHeight: 80px;
|
shadowHeight: 80px;
|
||||||
controlsAlign: align(top);
|
controlsAlign: align(bottom);
|
||||||
namePosition: point(64px, 44px);
|
namePosition: point(64px, 44px);
|
||||||
statusPosition: point(64px, 20px);
|
statusPosition: point(64px, 25px);
|
||||||
pinPosition: point(20px, 12px);
|
pinPosition: point(20px, 12px);
|
||||||
iconPosition: point(18px, 12px);
|
iconPosition: point(18px, 12px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,10 @@ rpl::producer<bool> LargeVideo::pinToggled() const {
|
||||||
return _pinButton.clicks() | rpl::map([=] { return !_pinned; });
|
return _pinButton.clicks() | rpl::map([=] { return !_pinned; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<QSize> LargeVideo::trackSizeValue() const {
|
||||||
|
return _trackSize.value();
|
||||||
|
}
|
||||||
|
|
||||||
void LargeVideo::setup(
|
void LargeVideo::setup(
|
||||||
rpl::producer<LargeVideoTrack> track,
|
rpl::producer<LargeVideoTrack> track,
|
||||||
rpl::producer<bool> pinned) {
|
rpl::producer<bool> pinned) {
|
||||||
|
@ -68,6 +72,7 @@ void LargeVideo::setup(
|
||||||
|
|
||||||
_trackLifetime.destroy();
|
_trackLifetime.destroy();
|
||||||
if (!track.track) {
|
if (!track.track) {
|
||||||
|
_trackSize = QSize();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
track.track->renderNextFrame(
|
track.track->renderNextFrame(
|
||||||
|
@ -75,6 +80,8 @@ void LargeVideo::setup(
|
||||||
const auto size = track.track->frameSize();
|
const auto size = track.track->frameSize();
|
||||||
if (size.isEmpty()) {
|
if (size.isEmpty()) {
|
||||||
track.track->markFrameShown();
|
track.track->markFrameShown();
|
||||||
|
} else {
|
||||||
|
_trackSize = size;
|
||||||
}
|
}
|
||||||
_content.update();
|
_content.update();
|
||||||
}, _trackLifetime);
|
}, _trackLifetime);
|
||||||
|
@ -249,20 +256,20 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
||||||
const auto iconLeft = width - _st.iconPosition.x() - icon.width();
|
const auto iconLeft = width - _st.iconPosition.x() - icon.width();
|
||||||
const auto iconTop = _topControls
|
const auto iconTop = _topControls
|
||||||
? _st.iconPosition.y()
|
? _st.iconPosition.y()
|
||||||
: (height - _st.iconPosition.y());
|
: (height - _st.iconPosition.y() - icon.height());
|
||||||
_track.row->paintMuteIcon(
|
_track.row->paintMuteIcon(
|
||||||
p,
|
p,
|
||||||
{ iconLeft, iconTop, icon.width(), icon.height() },
|
{ iconLeft, iconTop, icon.width(), icon.height() },
|
||||||
MembersRowStyle::LargeVideo);
|
MembersRowStyle::LargeVideo);
|
||||||
|
|
||||||
// Pin.
|
// Pin.
|
||||||
const auto pinWidth = st::groupCallLargeVideoPin.icon.width();
|
const auto &pin = st::groupCallLargeVideoPin.icon;
|
||||||
const auto pinLeft = _topControls
|
const auto pinLeft = _topControls
|
||||||
? (width - _st.pinPosition.x() - pinWidth)
|
? (width - _st.pinPosition.x() - pin.width())
|
||||||
: _st.pinPosition.x();
|
: _st.pinPosition.x();
|
||||||
const auto pinTop = _topControls
|
const auto pinTop = _topControls
|
||||||
? _st.pinPosition.y()
|
? _st.pinPosition.y()
|
||||||
: (height - _st.pinPosition.y());
|
: (height - _st.pinPosition.y() - pin.height());
|
||||||
_pin.paint(p, pinLeft, pinTop, _pinned ? 1. : 0.);
|
_pin.paint(p, pinLeft, pinTop, _pinned ? 1. : 0.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
void setGeometry(int x, int y, int width, int height);
|
void setGeometry(int x, int y, int width, int height);
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<bool> pinToggled() const;
|
[[nodiscard]] rpl::producer<bool> pinToggled() const;
|
||||||
|
[[nodiscard]] rpl::producer<QSize> trackSizeValue() const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
return _content.lifetime();
|
return _content.lifetime();
|
||||||
|
@ -109,6 +110,7 @@ private:
|
||||||
bool _topControls = false;
|
bool _topControls = false;
|
||||||
bool _pinned = false;
|
bool _pinned = false;
|
||||||
bool _controlsShown = true;
|
bool _controlsShown = true;
|
||||||
|
rpl::variable<QSize> _trackSize;
|
||||||
rpl::lifetime _trackLifetime;
|
rpl::lifetime _trackLifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1457,7 +1457,19 @@ Members::Members(
|
||||||
, _listController(std::make_unique<Controller>(call, parent))
|
, _listController(std::make_unique<Controller>(call, parent))
|
||||||
, _layout(_scroll->setOwnedWidget(
|
, _layout(_scroll->setOwnedWidget(
|
||||||
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
||||||
, _pinnedVideo(_layout->add(object_ptr<Ui::RpWidget>(_layout.get()))) {
|
, _pinnedVideoWrap(_layout->add(object_ptr<Ui::RpWidget>(_layout.get())))
|
||||||
|
, _pinnedVideo(
|
||||||
|
std::make_unique<LargeVideo>(
|
||||||
|
_pinnedVideoWrap.get(),
|
||||||
|
st::groupCallLargeVideoNarrow,
|
||||||
|
true,
|
||||||
|
_call->videoLargeTrackValue(
|
||||||
|
) | rpl::map([=](GroupCall::LargeTrack track) {
|
||||||
|
const auto row = track ? lookupRow(track.peer) : nullptr;
|
||||||
|
Assert(!track || row != nullptr);
|
||||||
|
return LargeVideoTrack{ row ? track.track : nullptr, row };
|
||||||
|
}),
|
||||||
|
_call->videoEndpointPinnedValue())) {
|
||||||
setupAddMember(call);
|
setupAddMember(call);
|
||||||
setupList();
|
setupList();
|
||||||
setupPinnedVideo();
|
setupPinnedVideo();
|
||||||
|
@ -1485,7 +1497,7 @@ auto Members::kickParticipantRequests() const
|
||||||
|
|
||||||
int Members::desiredHeight() const {
|
int Members::desiredHeight() const {
|
||||||
const auto addMember = _addMemberButton.current();
|
const auto addMember = _addMemberButton.current();
|
||||||
const auto top = _pinnedVideo->height()
|
const auto top = _pinnedVideoWrap->height()
|
||||||
+ (addMember ? addMember->height() : 0);
|
+ (addMember ? addMember->height() : 0);
|
||||||
const auto count = [&] {
|
const auto count = [&] {
|
||||||
if (const auto real = _call->lookupReal()) {
|
if (const auto real = _call->lookupReal()) {
|
||||||
|
@ -1602,6 +1614,7 @@ void Members::setMode(PanelMode mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
_pinnedVideo->setVisible(mode == PanelMode::Default);
|
||||||
_list->setMode((mode == PanelMode::Wide)
|
_list->setMode((mode == PanelMode::Wide)
|
||||||
? PeerListContent::Mode::Custom
|
? PeerListContent::Mode::Custom
|
||||||
: PeerListContent::Mode::Default);
|
: PeerListContent::Mode::Default);
|
||||||
|
@ -1635,6 +1648,15 @@ void Members::setupList() {
|
||||||
void Members::setupPinnedVideo() {
|
void Members::setupPinnedVideo() {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
|
_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());
|
||||||
|
|
||||||
// New video was pinned or mode changed.
|
// New video was pinned or mode changed.
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
_mode.changes() | rpl::filter(
|
_mode.changes() | rpl::filter(
|
||||||
|
@ -1646,102 +1668,22 @@ void Members::setupPinnedVideo() {
|
||||||
}, _scroll->lifetime());
|
}, _scroll->lifetime());
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_mode.value(),
|
_layout->widthValue(),
|
||||||
_call->videoLargeTrackValue()
|
_pinnedVideo->trackSizeValue()
|
||||||
) | rpl::map([](PanelMode mode, GroupCall::LargeTrack track) {
|
) | rpl::start_with_next([=](int width, QSize size) {
|
||||||
return (mode == PanelMode::Default) ? track.track : nullptr;
|
if (size.isEmpty() || !width) {
|
||||||
}) | rpl::distinct_until_changed(
|
_pinnedVideoWrap->resize(width, 0);
|
||||||
) | rpl::start_with_next([=](Webrtc::VideoTrack *track) {
|
|
||||||
_pinnedTrackLifetime.destroy();
|
|
||||||
if (!track) {
|
|
||||||
_pinnedVideo->resize(_pinnedVideo->width(), 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto frameSize = _pinnedTrackLifetime.make_state<QSize>();
|
const auto heightMin = (width * 9) / 16;
|
||||||
const auto applyFrameSize = [=](QSize size) {
|
const auto heightMax = (width * 3) / 4;
|
||||||
const auto width = _pinnedVideo->width();
|
const auto scaled = size.scaled(
|
||||||
if (size.isEmpty() || !width) {
|
QSize(width, heightMax),
|
||||||
return;
|
Qt::KeepAspectRatio);
|
||||||
}
|
const auto height = std::max(scaled.height(), heightMin);
|
||||||
const auto heightMin = (width * 9) / 16;
|
_pinnedVideoWrap->resize(width, height);
|
||||||
const auto heightMax = (width * 3) / 4;
|
_pinnedVideo->setGeometry(0, 0, width, height);
|
||||||
const auto scaled = size.scaled(
|
}, _pinnedVideo->lifetime());
|
||||||
QSize(width, heightMax),
|
|
||||||
Qt::KeepAspectRatio);
|
|
||||||
_pinnedVideo->resize(
|
|
||||||
width,
|
|
||||||
std::max(scaled.height(), heightMin));
|
|
||||||
};
|
|
||||||
track->renderNextFrame(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
const auto size = track->frameSize();
|
|
||||||
if (size.isEmpty()) {
|
|
||||||
track->markFrameShown();
|
|
||||||
} else {
|
|
||||||
if (*frameSize != size) {
|
|
||||||
*frameSize = size;
|
|
||||||
applyFrameSize(size);
|
|
||||||
}
|
|
||||||
_pinnedVideo->update();
|
|
||||||
}
|
|
||||||
}, _pinnedTrackLifetime);
|
|
||||||
|
|
||||||
_layout->widthValue(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
applyFrameSize(track->frameSize());
|
|
||||||
}, _pinnedTrackLifetime);
|
|
||||||
|
|
||||||
_pinnedVideo->paintRequest(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
const auto [image, rotation]
|
|
||||||
= track->frameOriginalWithRotation();
|
|
||||||
if (image.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto p = QPainter(_pinnedVideo);
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
|
||||||
using namespace Media::View;
|
|
||||||
const auto size = _pinnedVideo->size();
|
|
||||||
const auto scaled = FlipSizeByRotation(
|
|
||||||
image.size(),
|
|
||||||
rotation
|
|
||||||
).scaled(size, Qt::KeepAspectRatio);
|
|
||||||
const auto left = (size.width() - scaled.width()) / 2;
|
|
||||||
const auto top = (size.height() - scaled.height()) / 2;
|
|
||||||
const auto target = QRect(QPoint(left, top), scaled);
|
|
||||||
if (UsePainterRotation(rotation)) {
|
|
||||||
if (rotation) {
|
|
||||||
p.save();
|
|
||||||
p.rotate(rotation);
|
|
||||||
}
|
|
||||||
p.drawImage(RotatedRect(target, rotation), image);
|
|
||||||
if (rotation) {
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
} else if (rotation) {
|
|
||||||
p.drawImage(target, RotateFrameImage(image, rotation));
|
|
||||||
} else {
|
|
||||||
p.drawImage(target, image);
|
|
||||||
}
|
|
||||||
if (left > 0) {
|
|
||||||
p.fillRect(0, 0, left, size.height(), Qt::black);
|
|
||||||
}
|
|
||||||
if (const auto right = left + scaled.width()
|
|
||||||
; right < size.width()) {
|
|
||||||
const auto fill = size.width() - right;
|
|
||||||
p.fillRect(right, 0, fill, size.height(), Qt::black);
|
|
||||||
}
|
|
||||||
if (top > 0) {
|
|
||||||
p.fillRect(0, 0, size.width(), top, Qt::black);
|
|
||||||
}
|
|
||||||
if (const auto bottom = top + scaled.height()
|
|
||||||
; bottom < size.height()) {
|
|
||||||
const auto fill = size.height() - bottom;
|
|
||||||
p.fillRect(0, bottom, size.width(), fill, Qt::black);
|
|
||||||
}
|
|
||||||
track->markFrameShown();
|
|
||||||
}, _pinnedTrackLifetime);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Members::resizeEvent(QResizeEvent *e) {
|
void Members::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ class GroupCall;
|
||||||
|
|
||||||
namespace Calls::Group {
|
namespace Calls::Group {
|
||||||
|
|
||||||
|
class LargeVideo;
|
||||||
class MembersRow;
|
class MembersRow;
|
||||||
struct VolumeRequest;
|
struct VolumeRequest;
|
||||||
struct MuteRequest;
|
struct MuteRequest;
|
||||||
|
@ -91,7 +92,8 @@ private:
|
||||||
object_ptr<Ui::ScrollArea> _scroll;
|
object_ptr<Ui::ScrollArea> _scroll;
|
||||||
std::unique_ptr<Controller> _listController;
|
std::unique_ptr<Controller> _listController;
|
||||||
not_null<Ui::VerticalLayout*> _layout;
|
not_null<Ui::VerticalLayout*> _layout;
|
||||||
const not_null<Ui::RpWidget*> _pinnedVideo;
|
const not_null<Ui::RpWidget*> _pinnedVideoWrap;
|
||||||
|
const std::unique_ptr<LargeVideo> _pinnedVideo;
|
||||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||||
ListWidget *_list = nullptr;
|
ListWidget *_list = nullptr;
|
||||||
rpl::event_stream<> _addMemberRequests;
|
rpl::event_stream<> _addMemberRequests;
|
||||||
|
|
Loading…
Add table
Reference in a new issue