mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Add video placeholder if can't receive it.
This commit is contained in:
parent
b2bf8244dd
commit
f18e157e46
16 changed files with 249 additions and 79 deletions
|
@ -2058,6 +2058,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_ptt_delay" = "Push to Talk release delay: {delay}";
|
||||
"lng_group_call_share" = "Share Invite Link";
|
||||
"lng_group_call_noise_suppression" = "Enable Noise Suppression";
|
||||
"lng_group_call_limit#one" = "Video is only available\nfor the first {count} member";
|
||||
"lng_group_call_limit#other" = "Video is only available\nfor the first {count} members";
|
||||
"lng_group_call_share_speaker" = "Users with this link can speak";
|
||||
"lng_group_call_copy_speaker_link" = "Copy Speaker Link";
|
||||
"lng_group_call_copy_listener_link" = "Copy Listener Link";
|
||||
|
|
|
@ -1229,6 +1229,9 @@ groupCallVideoTile: GroupCallVideoTile {
|
|||
|
||||
groupCallVideoSmallSkip: 4px;
|
||||
groupCallVideoLargeSkip: 6px;
|
||||
groupCallVideoPlaceholderHeight: 212px;
|
||||
groupCallVideoPlaceholderIconTop: 50px;
|
||||
groupCallVideoPlaceholderTextTop: 120px;
|
||||
|
||||
groupCallTooltip: Tooltip(defaultTooltip) {
|
||||
textBg: groupCallMembersBg;
|
||||
|
|
|
@ -821,6 +821,9 @@ void GroupCall::setState(State state) {
|
|||
if (const auto call = _peer->groupCall(); call && call->id() == _id) {
|
||||
call->setInCall();
|
||||
}
|
||||
if (!videoIsWorking()) {
|
||||
refreshHasNotShownVideo();
|
||||
}
|
||||
}
|
||||
|
||||
if (false
|
||||
|
@ -1043,6 +1046,9 @@ void GroupCall::markEndpointActive(
|
|||
bool paused) {
|
||||
if (!endpoint) {
|
||||
return;
|
||||
} else if (active && !videoIsWorking()) {
|
||||
refreshHasNotShownVideo();
|
||||
return;
|
||||
}
|
||||
const auto i = _activeVideoTracks.find(endpoint);
|
||||
const auto changed = active
|
||||
|
@ -1067,26 +1073,34 @@ void GroupCall::markEndpointActive(
|
|||
.peer = endpoint.peer,
|
||||
}).first;
|
||||
const auto track = i->second.track.get();
|
||||
if (!track->frameSize().isEmpty()
|
||||
|| track->state() == Webrtc::VideoState::Paused) {
|
||||
|
||||
track->renderNextFrame(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto &activeTrack = _activeVideoTracks[endpoint];
|
||||
const auto size = track->frameSize();
|
||||
if (size.isEmpty()) {
|
||||
track->markFrameShown();
|
||||
} else if (!activeTrack.shown) {
|
||||
activeTrack.shown = true;
|
||||
markTrackShown(endpoint, true);
|
||||
}
|
||||
activeTrack.trackSize = size;
|
||||
}, i->second.lifetime);
|
||||
|
||||
const auto size = track->frameSize();
|
||||
i->second.trackSize = size;
|
||||
if (!size.isEmpty() || paused) {
|
||||
i->second.shown = true;
|
||||
shown = true;
|
||||
} else {
|
||||
auto hasFrame = track->renderNextFrame() | rpl::map([=] {
|
||||
return !track->frameSize().isEmpty();
|
||||
});
|
||||
auto isPaused = track->stateValue(
|
||||
) | rpl::map([=](Webrtc::VideoState state) {
|
||||
return (state == Webrtc::VideoState::Paused);
|
||||
});
|
||||
rpl::merge(
|
||||
std::move(hasFrame),
|
||||
std::move(isPaused)
|
||||
) | rpl::filter([=](bool shouldShow) {
|
||||
return shouldShow;
|
||||
track->stateValue(
|
||||
) | rpl::filter([=](Webrtc::VideoState state) {
|
||||
return (state == Webrtc::VideoState::Paused)
|
||||
&& !_activeVideoTracks[endpoint].shown;
|
||||
}) | rpl::start_with_next([=] {
|
||||
_activeVideoTracks[endpoint].shownTrackingLifetime.destroy();
|
||||
_activeVideoTracks[endpoint].shown = true;
|
||||
markTrackShown(endpoint, true);
|
||||
}, i->second.shownTrackingLifetime);
|
||||
}, i->second.lifetime);
|
||||
}
|
||||
addVideoOutput(i->first.id, { track->sink() });
|
||||
} else {
|
||||
|
@ -1109,10 +1123,11 @@ void GroupCall::markTrackShown(const VideoEndpoint &endpoint, bool shown) {
|
|||
const auto changed = shown
|
||||
? _shownVideoTracks.emplace(endpoint).second
|
||||
: _shownVideoTracks.remove(endpoint);
|
||||
if (changed) {
|
||||
_videoStreamShownUpdates.fire_copy({ endpoint, shown });
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
if (shown && changed && endpoint.type == VideoEndpointType::Screen) {
|
||||
_videoStreamShownUpdates.fire_copy({ endpoint, shown });
|
||||
if (shown && endpoint.type == VideoEndpointType::Screen) {
|
||||
crl::on_main(this, [=] {
|
||||
if (_shownVideoTracks.contains(endpoint)) {
|
||||
pinVideoEndpoint(endpoint);
|
||||
|
@ -2431,21 +2446,37 @@ void GroupCall::updateRequestedVideoChannelsDelayed() {
|
|||
});
|
||||
}
|
||||
|
||||
void GroupCall::refreshHasNotShownVideo() {
|
||||
if (!_joinState.ssrc || hasNotShownVideo()) {
|
||||
return;
|
||||
}
|
||||
const auto real = lookupReal();
|
||||
Assert(real != nullptr);
|
||||
|
||||
const auto hasVideo = [&](const Data::GroupCallParticipant &data) {
|
||||
return (data.peer != _joinAs)
|
||||
&& (!GetCameraEndpoint(data.videoParams).empty()
|
||||
|| !GetScreenEndpoint(data.videoParams).empty());
|
||||
};
|
||||
_hasNotShownVideo = _joinState.ssrc
|
||||
&& ranges::any_of(real->participants(), hasVideo);
|
||||
}
|
||||
|
||||
void GroupCall::fillActiveVideoEndpoints() {
|
||||
const auto real = lookupReal();
|
||||
Assert(real != nullptr);
|
||||
|
||||
if (const auto participant = real->participantByPeer(_joinAs)) {
|
||||
_videoIsWorking = participant->videoJoined;
|
||||
const auto me = real->participantByPeer(_joinAs);
|
||||
if (me && me->videoJoined) {
|
||||
_videoIsWorking = true;
|
||||
_hasNotShownVideo = false;
|
||||
} else {
|
||||
refreshHasNotShownVideo();
|
||||
_videoIsWorking = false;
|
||||
}
|
||||
if (!videoIsWorking()) {
|
||||
toggleVideo(false);
|
||||
toggleScreenSharing(std::nullopt);
|
||||
}
|
||||
|
||||
const auto &participants = real->participants();
|
||||
const auto &large = _videoEndpointLarge.current();
|
||||
auto largeFound = false;
|
||||
auto endpoints = _activeVideoTracks | ranges::views::transform([](
|
||||
|
@ -2469,7 +2500,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
|||
};
|
||||
using Type = VideoEndpointType;
|
||||
if (_videoIsWorking.current()) {
|
||||
for (const auto &participant : participants) {
|
||||
for (const auto &participant : real->participants()) {
|
||||
const auto camera = GetCameraEndpoint(participant.videoParams);
|
||||
if (camera != _cameraEndpoint
|
||||
&& camera != _screenEndpoint
|
||||
|
@ -2485,7 +2516,6 @@ void GroupCall::fillActiveVideoEndpoints() {
|
|||
feedOne({ Type::Screen, participant.peer, screen }, paused);
|
||||
}
|
||||
}
|
||||
const auto pausedState = Webrtc::VideoState::Paused;
|
||||
feedOne(
|
||||
{ Type::Camera, _joinAs, cameraSharingEndpoint() },
|
||||
isCameraPaused());
|
||||
|
|
|
@ -324,9 +324,11 @@ public:
|
|||
|
||||
struct VideoTrack {
|
||||
std::unique_ptr<Webrtc::VideoTrack> track;
|
||||
rpl::variable<QSize> trackSize;
|
||||
PeerData *peer = nullptr;
|
||||
rpl::lifetime shownTrackingLifetime;
|
||||
rpl::lifetime lifetime;
|
||||
Group::VideoQuality quality = Group::VideoQuality();
|
||||
bool shown = false;
|
||||
|
||||
[[nodiscard]] explicit operator bool() const {
|
||||
return (track != nullptr);
|
||||
|
@ -366,6 +368,12 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> videoIsWorkingValue() const {
|
||||
return _videoIsWorking.value();
|
||||
}
|
||||
[[nodiscard]] bool hasNotShownVideo() const {
|
||||
return _hasNotShownVideo.current();
|
||||
}
|
||||
[[nodiscard]] rpl::producer<bool> hasNotShownVideoValue() const {
|
||||
return _hasNotShownVideo.value();
|
||||
}
|
||||
|
||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||
void setCurrentVideoDevice(const QString &deviceId);
|
||||
|
@ -514,6 +522,7 @@ private:
|
|||
void updateRequestedVideoChannels();
|
||||
void updateRequestedVideoChannelsDelayed();
|
||||
void fillActiveVideoEndpoints();
|
||||
void refreshHasNotShownVideo();
|
||||
|
||||
void editParticipant(
|
||||
not_null<PeerData*> participantPeer,
|
||||
|
@ -570,6 +579,7 @@ private:
|
|||
rpl::variable<MuteState> _muted = MuteState::Muted;
|
||||
rpl::variable<bool> _canManage = false;
|
||||
rpl::variable<bool> _videoIsWorking = false;
|
||||
rpl::variable<bool> _hasNotShownVideo = false;
|
||||
bool _initialMuteStateSent = false;
|
||||
bool _acceptFields = false;
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/application.h" // Core::App().domain, .activeWindow.
|
||||
#include "main/main_domain.h" // Core::App().domain().activate.
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h" // account().appConfig().
|
||||
#include "main/main_app_config.h" // appConfig().get<double>().
|
||||
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration.
|
||||
#include "window/window_controller.h" // Controller::sessionController.
|
||||
#include "window/window_session_controller.h"
|
||||
|
@ -41,9 +43,110 @@ namespace {
|
|||
|
||||
constexpr auto kKeepRaisedHandStatusDuration = 3 * crl::time(1000);
|
||||
constexpr auto kShadowMaxAlpha = 74;
|
||||
constexpr auto kUserpicSizeForBlur = 40;
|
||||
constexpr auto kUserpicBlurRadius = 8;
|
||||
|
||||
using Row = MembersRow;
|
||||
|
||||
void SetupVideoPlaceholder(
|
||||
not_null<Ui::RpWidget*> widget,
|
||||
not_null<PeerData*> chat) {
|
||||
struct State {
|
||||
QImage blurred;
|
||||
QImage rounded;
|
||||
InMemoryKey key = {};
|
||||
std::shared_ptr<Data::CloudImageView> view;
|
||||
qint64 blurredCacheKey = 0;
|
||||
};
|
||||
const auto state = widget->lifetime().make_state<State>();
|
||||
const auto refreshBlurred = [=] {
|
||||
const auto key = chat->userpicUniqueKey(state->view);
|
||||
if (state->key == key && !state->blurred.isNull()) {
|
||||
return;
|
||||
}
|
||||
constexpr auto size = kUserpicSizeForBlur;
|
||||
state->key = key;
|
||||
state->blurred = QImage(
|
||||
QSize(size, size),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
{
|
||||
auto p = Painter(&state->blurred);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
chat->paintUserpicSquare(p, state->view, 0, 0, size);
|
||||
}
|
||||
state->blurred = Images::BlurLargeImage(
|
||||
std::move(state->blurred),
|
||||
kUserpicBlurRadius);
|
||||
widget->update();
|
||||
};
|
||||
const auto refreshRounded = [=](QSize size) {
|
||||
refreshBlurred();
|
||||
const auto key = state->blurred.cacheKey();
|
||||
if (state->rounded.size() == size && state->blurredCacheKey == key) {
|
||||
return;
|
||||
}
|
||||
state->blurredCacheKey = key;
|
||||
state->rounded = Images::prepare(
|
||||
state->blurred,
|
||||
size.width(),
|
||||
size.width(), // Square
|
||||
Images::Option::Smooth,
|
||||
size.width(),
|
||||
size.height());
|
||||
{
|
||||
auto p = QPainter(&state->rounded);
|
||||
p.fillRect(
|
||||
0,
|
||||
0,
|
||||
size.width(),
|
||||
size.height(),
|
||||
QColor(0, 0, 0, Viewport::kShadowMaxAlpha));
|
||||
}
|
||||
state->rounded = Images::prepare(
|
||||
std::move(state->rounded),
|
||||
size.width(),
|
||||
size.height(),
|
||||
(Images::Option::RoundedLarge | Images::Option::RoundedAll),
|
||||
size.width(),
|
||||
size.height());
|
||||
};
|
||||
chat->loadUserpic();
|
||||
refreshBlurred();
|
||||
|
||||
widget->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto size = QSize(
|
||||
widget->width(),
|
||||
widget->height() - st::groupCallVideoSmallSkip);
|
||||
refreshRounded(size * cIntRetinaFactor());
|
||||
|
||||
auto p = QPainter(widget);
|
||||
const auto inner = QRect(QPoint(), size);
|
||||
p.drawImage(inner, state->rounded);
|
||||
st::groupCallPaused.paint(
|
||||
p,
|
||||
(size.width() - st::groupCallPaused.width()) / 2,
|
||||
st::groupCallVideoPlaceholderIconTop,
|
||||
size.width());
|
||||
|
||||
const auto skip = st::groupCallVideoLargeSkip;
|
||||
const auto limit = chat->session().account().appConfig().get<double>(
|
||||
"groupcall_video_participants_max",
|
||||
30.);
|
||||
p.setPen(st::groupCallVideoTextFg);
|
||||
const auto text = QRect(
|
||||
skip,
|
||||
st::groupCallVideoPlaceholderTextTop,
|
||||
(size.width() - 2 * skip),
|
||||
size.height() - st::groupCallVideoPlaceholderTextTop);
|
||||
p.setFont(st::semiboldFont);
|
||||
p.drawText(
|
||||
text,
|
||||
tr::lng_group_call_limit(tr::now, lt_count, int(limit)),
|
||||
style::al_top);
|
||||
}, widget->lifetime());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class Members::Controller final
|
||||
|
@ -1467,6 +1570,7 @@ Members::Members(
|
|||
, _layout(_scroll->setOwnedWidget(
|
||||
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
||||
, _videoWrap(_layout->add(object_ptr<Ui::RpWidget>(_layout.get())))
|
||||
, _videoPlaceholder(std::make_unique<Ui::RpWidget>(_videoWrap.get()))
|
||||
, _viewport(
|
||||
std::make_unique<Viewport>(
|
||||
_videoWrap.get(),
|
||||
|
@ -1704,11 +1808,27 @@ void Members::trackViewportGeometry() {
|
|||
_scroll->scrollTopValue(
|
||||
) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime());
|
||||
|
||||
_viewport->fullHeightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
_videoWrap->resize(_videoWrap->width(), height);
|
||||
move();
|
||||
resize();
|
||||
rpl::combine(
|
||||
_layout->widthValue(),
|
||||
_call->hasNotShownVideoValue()
|
||||
) | rpl::start_with_next([=](int width, bool has) {
|
||||
const auto height = has ? st::groupCallVideoPlaceholderHeight : 0;
|
||||
_videoPlaceholder->setGeometry(0, 0, width, height);
|
||||
}, _videoPlaceholder->lifetime());
|
||||
|
||||
SetupVideoPlaceholder(_videoPlaceholder.get(), _call->peer());
|
||||
|
||||
rpl::combine(
|
||||
_videoPlaceholder->heightValue(),
|
||||
_viewport->fullHeightValue()
|
||||
) | rpl::start_with_next([=](int placeholder, int viewport) {
|
||||
_videoWrap->resize(
|
||||
_videoWrap->width(),
|
||||
std::max(placeholder, viewport));
|
||||
if (viewport > 0) {
|
||||
move();
|
||||
resize();
|
||||
}
|
||||
}, _viewport->lifetime());
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ private:
|
|||
std::unique_ptr<Controller> _listController;
|
||||
not_null<Ui::VerticalLayout*> _layout;
|
||||
const not_null<Ui::RpWidget*> _videoWrap;
|
||||
const std::unique_ptr<Ui::RpWidget> _videoPlaceholder;
|
||||
std::unique_ptr<Viewport> _viewport;
|
||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||
RpWidget *_topSkip = nullptr;
|
||||
|
|
|
@ -854,6 +854,7 @@ void Panel::setupVideo(not_null<Viewport*> viewport) {
|
|||
viewport->add(
|
||||
endpoint,
|
||||
VideoTileTrack{ track.track.get(), row },
|
||||
track.trackSize.value(),
|
||||
std::move(pinned));
|
||||
};
|
||||
for (const auto &[endpoint, track] : _call->activeVideoTracks()) {
|
||||
|
|
|
@ -225,10 +225,12 @@ void Viewport::setControlsShown(float64 shown) {
|
|||
void Viewport::add(
|
||||
const VideoEndpoint &endpoint,
|
||||
VideoTileTrack track,
|
||||
rpl::producer<QSize> trackSize,
|
||||
rpl::producer<bool> pinned) {
|
||||
_tiles.push_back(std::make_unique<VideoTile>(
|
||||
endpoint,
|
||||
track,
|
||||
std::move(trackSize),
|
||||
std::move(pinned),
|
||||
[=] { widget()->update(); }));
|
||||
|
||||
|
@ -711,11 +713,13 @@ void Viewport::updateTilesGeometryColumn(int outerWidth) {
|
|||
const auto layoutNext = [&](not_null<VideoTile*> tile) {
|
||||
const auto size = tile->trackOrUserpicSize();
|
||||
const auto shown = !size.isEmpty() && _large && tile != _large;
|
||||
const auto height = shown
|
||||
? st::groupCallNarrowVideoHeight
|
||||
: 0;
|
||||
setTileGeometry(tile, { 0, y + top, outerWidth, height });
|
||||
top += height ? (height + st::groupCallVideoSmallSkip) : 0;
|
||||
const auto height = st::groupCallNarrowVideoHeight;
|
||||
if (!shown) {
|
||||
tile->hide();
|
||||
} else {
|
||||
setTileGeometry(tile, { 0, y + top, outerWidth, height });
|
||||
top += height + st::groupCallVideoSmallSkip;
|
||||
}
|
||||
};
|
||||
const auto topPeer = _large ? _large->row()->peer().get() : nullptr;
|
||||
const auto reorderNeeded = [&] {
|
||||
|
|
|
@ -39,6 +39,7 @@ enum class VideoQuality;
|
|||
struct VideoTileTrack {
|
||||
Webrtc::VideoTrack *track = nullptr;
|
||||
MembersRow *row = nullptr;
|
||||
rpl::variable<QSize> trackSize;
|
||||
|
||||
[[nodiscard]] explicit operator bool() const {
|
||||
return track != nullptr;
|
||||
|
@ -77,6 +78,7 @@ public:
|
|||
void add(
|
||||
const VideoEndpoint &endpoint,
|
||||
VideoTileTrack track,
|
||||
rpl::producer<QSize> trackSize,
|
||||
rpl::producer<bool> pinned);
|
||||
void remove(const VideoEndpoint &endpoint);
|
||||
void showLarge(const VideoEndpoint &endpoint);
|
||||
|
@ -91,6 +93,8 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::lifetime &lifetime();
|
||||
|
||||
static constexpr auto kShadowMaxAlpha = 80;
|
||||
|
||||
private:
|
||||
struct Textures;
|
||||
class VideoTile;
|
||||
|
@ -132,8 +136,6 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
static constexpr auto kShadowMaxAlpha = 80;
|
||||
|
||||
void setup();
|
||||
[[nodiscard]] bool wide() const;
|
||||
|
||||
|
|
|
@ -320,7 +320,6 @@ Viewport::RendererGL::RendererGL(not_null<Viewport*> owner)
|
|||
void Viewport::RendererGL::init(
|
||||
not_null<QOpenGLWidget*> widget,
|
||||
QOpenGLFunctions &f) {
|
||||
_factor = widget->devicePixelRatio();
|
||||
_frameBuffer.emplace();
|
||||
_frameBuffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
|
||||
_frameBuffer->create();
|
||||
|
@ -427,7 +426,11 @@ void Viewport::RendererGL::setDefaultViewport(QOpenGLFunctions &f) {
|
|||
void Viewport::RendererGL::paint(
|
||||
not_null<QOpenGLWidget*> widget,
|
||||
QOpenGLFunctions &f) {
|
||||
_factor = widget->devicePixelRatio();
|
||||
const auto factor = widget->devicePixelRatio();
|
||||
if (_factor != factor) {
|
||||
_factor = factor;
|
||||
_buttons.invalidate();
|
||||
}
|
||||
_viewport = widget->size();
|
||||
|
||||
const auto defaultFramebufferObject = widget->defaultFramebufferObject();
|
||||
|
@ -1054,7 +1057,6 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
|||
if (_buttons) {
|
||||
return;
|
||||
}
|
||||
const auto factor = cIntRetinaFactor();
|
||||
const auto pinOnSize = VideoTile::PinInnerSize(true);
|
||||
const auto pinOffSize = VideoTile::PinInnerSize(false);
|
||||
const auto backSize = VideoTile::BackInnerSize();
|
||||
|
@ -1074,18 +1076,18 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
|||
+ backSize.height()
|
||||
+ muteSize.height()
|
||||
+ pausedSize.height()));
|
||||
const auto imageSize = fullSize * factor;
|
||||
const auto imageSize = fullSize * _factor;
|
||||
auto image = _buttons.takeImage();
|
||||
if (image.size() != imageSize) {
|
||||
image = QImage(imageSize, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
image.fill(Qt::transparent);
|
||||
image.setDevicePixelRatio(cRetinaFactor());
|
||||
image.setDevicePixelRatio(_factor);
|
||||
{
|
||||
auto p = Painter(&image);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
|
||||
_pinOn = QRect(QPoint(), pinOnSize * factor);
|
||||
_pinOn = QRect(QPoint(), pinOnSize * _factor);
|
||||
VideoTile::PaintPinButton(
|
||||
p,
|
||||
true,
|
||||
|
@ -1096,7 +1098,9 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
|||
&_pinIcon);
|
||||
|
||||
const auto pinOffTop = pinOnSize.height();
|
||||
_pinOff = QRect(QPoint(0, pinOffTop) * factor, pinOffSize * factor);
|
||||
_pinOff = QRect(
|
||||
QPoint(0, pinOffTop) * _factor,
|
||||
pinOffSize * _factor);
|
||||
VideoTile::PaintPinButton(
|
||||
p,
|
||||
false,
|
||||
|
@ -1107,7 +1111,7 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
|||
&_pinIcon);
|
||||
|
||||
const auto backTop = pinOffTop + pinOffSize.height();
|
||||
_back = QRect(QPoint(0, backTop) * factor, backSize * factor);
|
||||
_back = QRect(QPoint(0, backTop) * _factor, backSize * _factor);
|
||||
VideoTile::PaintBackButton(
|
||||
p,
|
||||
0,
|
||||
|
@ -1116,16 +1120,18 @@ void Viewport::RendererGL::ensureButtonsImage() {
|
|||
&_pinBackground);
|
||||
|
||||
const auto muteTop = backTop + backSize.height();
|
||||
_muteOn = QRect(QPoint(0, muteTop) * factor, muteSize * factor);
|
||||
_muteOn = QRect(QPoint(0, muteTop) * _factor, muteSize * _factor);
|
||||
_muteIcon.paint(p, { 0, muteTop }, 1.);
|
||||
|
||||
_muteOff = QRect(
|
||||
QPoint(muteSize.width(), muteTop) * factor,
|
||||
muteSize * factor);
|
||||
QPoint(muteSize.width(), muteTop) * _factor,
|
||||
muteSize * _factor);
|
||||
_muteIcon.paint(p, { muteSize.width(), muteTop }, 0.);
|
||||
|
||||
const auto pausedTop = muteTop + muteSize.height();
|
||||
_paused = QRect(QPoint(0, pausedTop) * factor, pausedSize * factor);
|
||||
_paused = QRect(
|
||||
QPoint(0, pausedTop) * _factor,
|
||||
pausedSize * _factor);
|
||||
st::groupCallPaused.paint(p, 0, pausedTop, fullSize.width());
|
||||
}
|
||||
_buttons.setImage(std::move(image));
|
||||
|
|
|
@ -25,11 +25,13 @@ constexpr auto kPausedVideoSize = 90;
|
|||
Viewport::VideoTile::VideoTile(
|
||||
const VideoEndpoint &endpoint,
|
||||
VideoTileTrack track,
|
||||
rpl::producer<QSize> trackSize,
|
||||
rpl::producer<bool> pinned,
|
||||
Fn<void()> update)
|
||||
: _endpoint(endpoint)
|
||||
, _update(std::move(update))
|
||||
, _track(track) {
|
||||
, _track(track)
|
||||
, _trackSize(std::move(trackSize)) {
|
||||
Expects(track.track != nullptr);
|
||||
Expects(track.row != nullptr);
|
||||
|
||||
|
@ -254,19 +256,7 @@ void Viewport::VideoTile::setup(rpl::producer<bool> pinned) {
|
|||
}, _lifetime);
|
||||
|
||||
_track.track->renderNextFrame(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto size = _track.track->frameSize();
|
||||
if (size.isEmpty()) {
|
||||
_track.track->markFrameShown();
|
||||
} else {
|
||||
_trackSize = size;
|
||||
}
|
||||
_update();
|
||||
}, _lifetime);
|
||||
|
||||
if (const auto size = _track.track->frameSize(); !size.isEmpty()) {
|
||||
_trackSize = size;
|
||||
}
|
||||
) | rpl::start_with_next(_update, _lifetime);
|
||||
|
||||
updateTopControlsSize();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
VideoTile(
|
||||
const VideoEndpoint &endpoint,
|
||||
VideoTileTrack track,
|
||||
rpl::producer<QSize> trackSize,
|
||||
rpl::producer<bool> pinned,
|
||||
Fn<void()> update);
|
||||
|
||||
|
|
|
@ -304,10 +304,10 @@ void Application::showOpenGLCrashNotification() {
|
|||
Local::writeSettings();
|
||||
};
|
||||
_window->show(Box<ConfirmBox>(
|
||||
"Last time OpenGL crashed on initialization. "
|
||||
"Perhaps it is a problem with your graphics card driver.\n\n"
|
||||
"Right now OpenGL was disabled. You can try to enable it back "
|
||||
"or keep it disabled, if it continues crashing.",
|
||||
"There may be a problem with your graphics drivers and OpenGL. "
|
||||
"Try updating your drivers.\n\n"
|
||||
"OpenGL has been disabled. You can try to enable it again "
|
||||
"or keep it disabled if crashes continue.",
|
||||
"Enable",
|
||||
"Keep Disabled",
|
||||
enable,
|
||||
|
|
|
@ -3274,7 +3274,6 @@ void OverlayWidget::paint(not_null<Renderer*> renderer) {
|
|||
}
|
||||
paintRadialLoading(renderer);
|
||||
} else {
|
||||
int a = 0;
|
||||
if (_themePreviewShown) {
|
||||
renderer->paintThemePreview(_themePreviewRect);
|
||||
} else if (documentBubbleShown() && !_docRect.isEmpty()) {
|
||||
|
|
|
@ -406,21 +406,22 @@ void Pip::RendererGL::paintTransformedContent(
|
|||
_f->glActiveTexture(rgbaFrame ? GL_TEXTURE1 : GL_TEXTURE3);
|
||||
_shadowImage.bind(*_f);
|
||||
|
||||
const auto globalFactor = cIntRetinaFactor();
|
||||
const auto fadeAlpha = st::radialBg->c.alphaF() * geometry.fade;
|
||||
const auto roundRect = transformRect(RoundingRect(geometry));
|
||||
program->setUniformValue("roundRect", Uniform(roundRect));
|
||||
program->setUniformValue("h_texture", GLint(rgbaFrame ? 1 : 3));
|
||||
program->setUniformValue("h_size", QSizeF(_shadowImage.image().size()));
|
||||
program->setUniformValue("h_extend", QVector4D(
|
||||
st::callShadow.extend.left(),
|
||||
st::callShadow.extend.top(),
|
||||
st::callShadow.extend.right(),
|
||||
st::callShadow.extend.bottom()));
|
||||
st::callShadow.extend.left() * globalFactor,
|
||||
st::callShadow.extend.top() * globalFactor,
|
||||
st::callShadow.extend.right() * globalFactor,
|
||||
st::callShadow.extend.bottom() * globalFactor));
|
||||
program->setUniformValue("h_components", QVector4D(
|
||||
float(st::callShadow.topLeft.width()),
|
||||
float(st::callShadow.topLeft.height()),
|
||||
float(st::callShadow.left.width()),
|
||||
float(st::callShadow.top.height())));
|
||||
float(st::callShadow.topLeft.width() * globalFactor),
|
||||
float(st::callShadow.topLeft.height() * globalFactor),
|
||||
float(st::callShadow.left.width() * globalFactor),
|
||||
float(st::callShadow.top.height() * globalFactor)));
|
||||
program->setUniformValue(
|
||||
"roundRadius",
|
||||
GLfloat(st::roundRadiusLarge * _factor));
|
||||
|
|
2
Telegram/ThirdParty/tgcalls
vendored
2
Telegram/ThirdParty/tgcalls
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 9adb220f798cadc0848d3e1efbf32fb2a98a3bcb
|
||||
Subproject commit d147f286cfe2a23c49c438a63be9aa1c0a04344b
|
Loading…
Add table
Reference in a new issue