Show "Video is paused" in wide panel mode.

This commit is contained in:
John Preston 2021-06-15 16:49:53 +04:00
parent 8dac6896d6
commit df28da4d97
8 changed files with 159 additions and 51 deletions

View file

@ -2060,6 +2060,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_noise_suppression" = "Enable Noise Suppression"; "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#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_limit#other" = "Video is only available\nfor the first {count} members";
"lng_group_call_video_paused" = "Video is paused";
"lng_group_call_share_speaker" = "Users with this link can speak"; "lng_group_call_share_speaker" = "Users with this link can speak";
"lng_group_call_copy_speaker_link" = "Copy Speaker Link"; "lng_group_call_copy_speaker_link" = "Copy Speaker Link";
"lng_group_call_copy_listener_link" = "Copy Listener Link"; "lng_group_call_copy_listener_link" = "Copy Listener Link";

View file

@ -1150,6 +1150,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
: Variants::Tcp; : Variants::Tcp;
const auto mtproto = &_account->mtp(); const auto mtproto = &_account->mtp();
const auto dcId = mtproto->mainDcId(); const auto dcId = mtproto->mainDcId();
const auto forFiles = false;
item.state = ItemState::Checking; item.state = ItemState::Checking;
const auto setup = [&](Checker &checker, const bytes::vector &secret) { const auto setup = [&](Checker &checker, const bytes::vector &secret) {
@ -1168,7 +1169,8 @@ void ProxiesBoxController::refreshChecker(Item &item) {
item.data.host, item.data.host,
item.data.port, item.data.port,
secret, secret,
dcId); dcId,
forFiles);
item.checkerv6 = nullptr; item.checkerv6 = nullptr;
} else { } else {
const auto options = mtproto->dcOptions().lookup( const auto options = mtproto->dcOptions().lookup(
@ -1190,7 +1192,8 @@ void ProxiesBoxController::refreshChecker(Item &item) {
QString::fromStdString(endpoint.ip), QString::fromStdString(endpoint.ip),
endpoint.port, endpoint.port,
endpoint.secret, endpoint.secret,
dcId); dcId,
forFiles);
}; };
connect(item.checker, Variants::IPv4); connect(item.checker, Variants::IPv4);
connect(item.checkerv6, Variants::IPv6); connect(item.checkerv6, Variants::IPv6);

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "webrtc/webrtc_video_track.h" #include "webrtc/webrtc_video_track.h"
#include "media/view/media_view_pip.h" #include "media/view/media_view_pip.h"
#include "calls/group/calls_group_members_row.h" #include "calls/group/calls_group_members_row.h"
#include "lang/lang_keys.h"
#include "ui/gl/gl_shader.h" #include "ui/gl/gl_shader.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "styles/style_calls.h" #include "styles/style_calls.h"
@ -32,7 +33,7 @@ constexpr auto kBlurOpacity = 0.65;
constexpr auto kDitherNoiseAmount = 0.002; constexpr auto kDitherNoiseAmount = 0.002;
constexpr auto kMinCameraVisiblePart = 0.75; constexpr auto kMinCameraVisiblePart = 0.75;
constexpr auto kQuads = 8; constexpr auto kQuads = 9;
constexpr auto kQuadVertices = kQuads * 4; constexpr auto kQuadVertices = kQuads * 4;
constexpr auto kQuadValues = kQuadVertices * 4; constexpr auto kQuadValues = kQuadVertices * 4;
constexpr auto kValues = kQuadValues + 8; // Blur texture coordinates. constexpr auto kValues = kQuadValues + 8; // Blur texture coordinates.
@ -554,16 +555,50 @@ void Viewport::RendererGL::paintTile(
texCoords.end()); texCoords.end());
} }
// Paused. const auto nameTop = y + (height
const auto &pauseIcon = st::groupCallPaused; - st.namePosition.y()
const auto pausedIcon = _buttons.texturedRect( - st::semiboldFont->height);
// Paused icon and text.
const auto middle = (st::groupCallVideoPlaceholderHeight
- st::groupCallPaused.height()) / 2;
const auto pausedSpace = (nameTop - y)
- st::groupCallPaused.height()
- st::semiboldFont->height;
const auto pauseIconSkip = middle - st::groupCallVideoPlaceholderIconTop;
const auto pauseTextSkip = st::groupCallVideoPlaceholderTextTop
- st::groupCallVideoPlaceholderIconTop;
const auto pauseIconTop = !_owner->wide()
? (y + (height - st::groupCallPaused.height()) / 2)
: (pausedSpace < 3 * st::semiboldFont->height)
? (pausedSpace / 3)
: std::min(
y + (height / 2) - pauseIconSkip,
(nameTop
- st::semiboldFont->height * 3
- st::groupCallPaused.height()));
const auto pauseTextTop = (pausedSpace < 3 * st::semiboldFont->height)
? (nameTop - (pausedSpace / 3) - st::semiboldFont->height)
: std::min(
pauseIconTop + pauseTextSkip,
nameTop - st::semiboldFont->height * 2);
const auto pauseIcon = _buttons.texturedRect(
QRect( QRect(
geometry.x() + (geometry.width() - pauseIcon.width()) / 2, x + (width - st::groupCallPaused.width()) / 2,
geometry.y() + (geometry.height() - pauseIcon.height()) / 2, pauseIconTop,
pauseIcon.width(), st::groupCallPaused.width(),
pauseIcon.height()), st::groupCallPaused.height()),
_paused); _paused);
const auto pausedRect = transformRect(pausedIcon.geometry); const auto pauseRect = transformRect(pauseIcon.geometry);
const auto pausedPosition = QPoint(
x + (width - (_pausedTextRect.width() / cIntRetinaFactor())) / 2,
pauseTextTop);
const auto pausedText = _names.texturedRect(
QRect(pausedPosition, _pausedTextRect.size() / cIntRetinaFactor()),
_pausedTextRect);
const auto pausedRect = transformRect(pausedText.geometry);
// Pin. // Pin.
const auto pin = _buttons.texturedRect( const auto pin = _buttons.texturedRect(
@ -597,10 +632,7 @@ void Viewport::RendererGL::paintTile(
// Name. // Name.
const auto namePosition = QPoint( const auto namePosition = QPoint(
x + st.namePosition.x(), x + st.namePosition.x(),
y + (height nameTop + nameShift);
- st.namePosition.y()
- st::semiboldFont->height
+ nameShift));
const auto name = _names.texturedRect( const auto name = _names.texturedRect(
QRect(namePosition, tileData.nameRect.size() / cIntRetinaFactor()), QRect(namePosition, tileData.nameRect.size() / cIntRetinaFactor()),
tileData.nameRect, tileData.nameRect,
@ -706,17 +738,30 @@ void Viewport::RendererGL::paintTile(
name.texture.left(), name.texture.top(), name.texture.left(), name.texture.top(),
// Paused icon. // Paused icon.
pauseRect.left(), pauseRect.top(),
pauseIcon.texture.left(), pauseIcon.texture.bottom(),
pauseRect.right(), pauseRect.top(),
pauseIcon.texture.right(), pauseIcon.texture.bottom(),
pauseRect.right(), pauseRect.bottom(),
pauseIcon.texture.right(), pauseIcon.texture.top(),
pauseRect.left(), pauseRect.bottom(),
pauseIcon.texture.left(), pauseIcon.texture.top(),
// Paused text.
pausedRect.left(), pausedRect.top(), pausedRect.left(), pausedRect.top(),
pausedIcon.texture.left(), pausedIcon.texture.bottom(), pausedText.texture.left(), pausedText.texture.bottom(),
pausedRect.right(), pausedRect.top(), pausedRect.right(), pausedRect.top(),
pausedIcon.texture.right(), pausedIcon.texture.bottom(), pausedText.texture.right(), pausedText.texture.bottom(),
pausedRect.right(), pausedRect.bottom(), pausedRect.right(), pausedRect.bottom(),
pausedIcon.texture.right(), pausedIcon.texture.top(), pausedText.texture.right(), pausedText.texture.top(),
pausedRect.left(), pausedRect.bottom(), pausedRect.left(), pausedRect.bottom(),
pausedIcon.texture.left(), pausedIcon.texture.top(), pausedText.texture.left(), pausedText.texture.top(),
}; };
_frameBuffer->bind(); _frameBuffer->bind();
@ -787,7 +832,9 @@ void Viewport::RendererGL::paintTile(
const auto pinVisible = _owner->wide() const auto pinVisible = _owner->wide()
&& (pin.geometry.bottom() > y); && (pin.geometry.bottom() > y);
if (nameShift == fullNameShift && !pinVisible && paused == 0.) { const auto nameVisible = (nameShift != fullNameShift);
const auto pausedVisible = (paused > 0.);
if (!nameVisible && !pinVisible && !pausedVisible) {
return; return;
} }
@ -804,31 +851,40 @@ void Viewport::RendererGL::paintTile(
f.glActiveTexture(GL_TEXTURE0); f.glActiveTexture(GL_TEXTURE0);
_buttons.bind(f); _buttons.bind(f);
if (paused > 0) { // Paused icon.
if (pausedVisible) {
_imageProgram->setUniformValue("g_opacity", GLfloat(paused)); _imageProgram->setUniformValue("g_opacity", GLfloat(paused));
FillTexturedRectangle(f, &*_imageProgram, 30); FillTexturedRectangle(f, &*_imageProgram, 30);
} }
_imageProgram->setUniformValue("g_opacity", GLfloat(1.f)); _imageProgram->setUniformValue("g_opacity", GLfloat(1.f));
// Pin.
if (pinVisible) { if (pinVisible) {
FillTexturedRectangle(f, &*_imageProgram, 14); FillTexturedRectangle(f, &*_imageProgram, 14);
FillTexturedRectangle(f, &*_imageProgram, 18); FillTexturedRectangle(f, &*_imageProgram, 18);
} }
if (nameShift == fullNameShift) {
return;
}
// Mute. // Mute.
if (!muteRect.empty()) { if (nameVisible && !muteRect.empty()) {
FillTexturedRectangle(f, &*_imageProgram, 22); FillTexturedRectangle(f, &*_imageProgram, 22);
} }
if (!nameVisible && !pausedVisible) {
return;
}
_names.bind(f);
// Name. // Name.
if (!nameRect.empty()) { if (nameVisible && !nameRect.empty()) {
_names.bind(f);
FillTexturedRectangle(f, &*_imageProgram, 26); FillTexturedRectangle(f, &*_imageProgram, 26);
} }
// Paused text.
if (pausedVisible && _owner->wide()) {
_imageProgram->setUniformValue("g_opacity", GLfloat(paused));
FillTexturedRectangle(f, &*_imageProgram, 34);
}
} }
void Viewport::RendererGL::prepareObjects( void Viewport::RendererGL::prepareObjects(
@ -1143,12 +1199,15 @@ void Viewport::RendererGL::validateDatas() {
const auto count = int(tiles.size()); const auto count = int(tiles.size());
const auto factor = cIntRetinaFactor(); const auto factor = cIntRetinaFactor();
const auto nameHeight = st::semiboldFont->height * factor; const auto nameHeight = st::semiboldFont->height * factor;
const auto pausedText = tr::lng_group_call_video_paused(tr::now);
const auto pausedBottom = nameHeight;
const auto pausedWidth = st::semiboldFont->width(pausedText) * factor;
struct Request { struct Request {
int index = 0; int index = 0;
bool updating = false; bool updating = false;
}; };
auto requests = std::vector<Request>(); auto requests = std::vector<Request>();
auto available = _names.image().width(); auto available = std::max(_names.image().width(), pausedWidth);
for (auto &data : _tileData) { for (auto &data : _tileData) {
data.stale = true; data.stale = true;
} }
@ -1180,7 +1239,7 @@ void Viewport::RendererGL::validateDatas() {
if (peer != j->peer if (peer != j->peer
|| peer->nameVersion != j->nameVersion || peer->nameVersion != j->nameVersion
|| width != j->nameRect.width()) { || width != j->nameRect.width()) {
const auto nameTop = index * nameHeight; const auto nameTop = pausedBottom + index * nameHeight;
j->nameRect = QRect(0, nameTop, width, nameHeight); j->nameRect = QRect(0, nameTop, width, nameHeight);
requests.push_back({ .index = i, .updating = true }); requests.push_back({ .index = i, .updating = true });
} }
@ -1225,16 +1284,19 @@ void Viewport::RendererGL::validateDatas() {
.pause = paused, .pause = paused,
}); });
} }
const auto nameTop = pausedBottom + index * nameHeight;
_tileData[index].nameVersion = peer->nameVersion; _tileData[index].nameVersion = peer->nameVersion;
_tileData[index].nameRect = QRect( _tileData[index].nameRect = QRect(
0, 0,
index * nameHeight, nameTop,
nameWidth(i), nameWidth(i),
nameHeight); nameHeight);
_tileDataIndices[i] = index; _tileDataIndices[i] = index;
} }
auto image = _names.takeImage(); auto image = _names.takeImage();
const auto imageSize = QSize(available, _tileData.size() * nameHeight); const auto imageSize = QSize(
available,
pausedBottom + _tileData.size() * nameHeight);
const auto allocate = (image.size() != imageSize); const auto allocate = (image.size() != imageSize);
auto paintToImage = allocate auto paintToImage = allocate
? QImage(imageSize, QImage::Format_ARGB32_Premultiplied) ? QImage(imageSize, QImage::Format_ARGB32_Premultiplied)
@ -1245,6 +1307,7 @@ void Viewport::RendererGL::validateDatas() {
} }
{ {
auto p = Painter(&paintToImage); auto p = Painter(&paintToImage);
p.setPen(st::groupCallVideoTextFg);
if (!image.isNull()) { if (!image.isNull()) {
p.setCompositionMode(QPainter::CompositionMode_Source); p.setCompositionMode(QPainter::CompositionMode_Source);
p.drawImage(0, 0, image); p.drawImage(0, 0, image);
@ -1265,8 +1328,11 @@ void Viewport::RendererGL::validateDatas() {
Qt::transparent); Qt::transparent);
} }
p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setCompositionMode(QPainter::CompositionMode_SourceOver);
} else if (allocate) {
p.setFont(st::semiboldFont);
p.drawText(0, st::semiboldFont->ascent, pausedText);
_pausedTextRect = QRect(0, 0, pausedWidth, nameHeight);
} }
p.setPen(st::groupCallVideoTextFg);
for (const auto &request : requests) { for (const auto &request : requests) {
const auto i = request.index; const auto i = request.index;
const auto index = _tileDataIndices[i]; const auto index = _tileDataIndices[i];

View file

@ -152,6 +152,7 @@ private:
QRect _paused; QRect _paused;
Ui::GL::Image _names; Ui::GL::Image _names;
QRect _pausedTextRect;
std::vector<TileData> _tileData; std::vector<TileData> _tileData;
std::vector<int> _tileDataIndices; std::vector<int> _tileDataIndices;

View file

@ -232,9 +232,48 @@ void Viewport::RendererSW::paintTileControls(
&_pinBackground); &_pinBackground);
} }
const auto &st = st::groupCallVideoTile;
const auto nameTop = y + (height
- st.namePosition.y()
- st::semiboldFont->height);
if (_pausedFrame) { if (_pausedFrame) {
p.fillRect(x, y, width, height, QColor(0, 0, 0, kShadowMaxAlpha)); p.fillRect(x, y, width, height, QColor(0, 0, 0, kShadowMaxAlpha));
st::groupCallPaused.paintInCenter(p, { x, y, width, height });
const auto middle = (st::groupCallVideoPlaceholderHeight
- st::groupCallPaused.height()) / 2;
const auto pausedSpace = (nameTop - y)
- st::groupCallPaused.height()
- st::semiboldFont->height;
const auto pauseIconSkip = middle - st::groupCallVideoPlaceholderIconTop;
const auto pauseTextSkip = st::groupCallVideoPlaceholderTextTop
- st::groupCallVideoPlaceholderIconTop;
const auto pauseIconTop = !_owner->wide()
? (y + (height - st::groupCallPaused.height()) / 2)
: (pausedSpace < 3 * st::semiboldFont->height)
? (pausedSpace / 3)
: std::min(
y + (height / 2) - pauseIconSkip,
(nameTop
- st::semiboldFont->height * 3
- st::groupCallPaused.height()));
const auto pauseTextTop = (pausedSpace < 3 * st::semiboldFont->height)
? (nameTop - (pausedSpace / 3) - st::semiboldFont->height)
: std::min(
pauseIconTop + pauseTextSkip,
nameTop - st::semiboldFont->height * 2);
st::groupCallPaused.paint(
p,
x + (width - st::groupCallPaused.width()) / 2,
pauseIconTop,
width);
if (_owner->wide()) {
p.drawText(
QRect(x, pauseTextTop, width, y + height - pauseTextTop),
tr::lng_group_call_video_paused(tr::now),
style::al_top);
}
} }
const auto shown = _owner->_controlsShownRatio; const auto shown = _owner->_controlsShownRatio;
@ -242,7 +281,6 @@ void Viewport::RendererSW::paintTileControls(
return; return;
} }
const auto &st = st::groupCallVideoTile;
const auto fullShift = st.namePosition.y() + st::normalFont->height; const auto fullShift = st.namePosition.y() + st::normalFont->height;
const auto shift = anim::interpolate(fullShift, 0, shown); const auto shift = anim::interpolate(fullShift, 0, shown);
@ -291,11 +329,12 @@ void Viewport::RendererSW::paintTileControls(
- st.iconPosition.x() - icon.width() - st.iconPosition.x() - icon.width()
- st.namePosition.x(); - st.namePosition.x();
const auto nameLeft = x + st.namePosition.x(); const auto nameLeft = x + st.namePosition.x();
const auto nameTop = y + (height row->name().drawLeftElided(
- st.namePosition.y() p,
- st::semiboldFont->height nameLeft,
+ shift); nameTop + shift,
row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width); hasWidth,
width);
} }
} // namespace Calls::Group } // namespace Calls::Group

View file

@ -607,8 +607,10 @@ void OverlayWidget::RendererGL::paintUsingRaster(
} }
method(Painter(&raster)); method(Painter(&raster));
image.setImage(std::move(raster)); _f->glActiveTexture(GL_TEXTURE0);
image.bind(*_f, size);
image.setImage(std::move(raster), size);
image.bind(*_f);
const auto textured = image.texturedRect(rect, QRect(QPoint(), size)); const auto textured = image.texturedRect(rect, QRect(QPoint(), size));
const auto geometry = transformRect(textured.geometry); const auto geometry = transformRect(textured.geometry);
@ -634,9 +636,6 @@ void OverlayWidget::RendererGL::paintUsingRaster(
_imageProgram->setUniformValue("viewport", _uniformViewport); _imageProgram->setUniformValue("viewport", _uniformViewport);
_imageProgram->setUniformValue("s_texture", GLint(0)); _imageProgram->setUniformValue("s_texture", GLint(0));
_f->glActiveTexture(GL_TEXTURE0);
image.bind(*_f, size);
toggleBlending(transparent); toggleBlending(transparent);
FillTexturedRectangle(*_f, &*_imageProgram, bufferOffset); FillTexturedRectangle(*_f, &*_imageProgram, bufferOffset);
} }

View file

@ -694,8 +694,10 @@ void Pip::RendererGL::paintUsingRaster(
} }
method(Painter(&raster)); method(Painter(&raster));
image.setImage(std::move(raster)); _f->glActiveTexture(GL_TEXTURE0);
image.bind(*_f, size);
image.setImage(std::move(raster), size);
image.bind(*_f);
const auto textured = image.texturedRect(rect, QRect(QPoint(), size)); const auto textured = image.texturedRect(rect, QRect(QPoint(), size));
const auto geometry = transformRect(textured.geometry); const auto geometry = transformRect(textured.geometry);
@ -722,9 +724,6 @@ void Pip::RendererGL::paintUsingRaster(
_imageProgram->setUniformValue("s_texture", GLint(0)); _imageProgram->setUniformValue("s_texture", GLint(0));
_imageProgram->setUniformValue("g_opacity", GLfloat(1)); _imageProgram->setUniformValue("g_opacity", GLfloat(1));
_f->glActiveTexture(GL_TEXTURE0);
image.bind(*_f, size);
toggleBlending(transparent); toggleBlending(transparent);
FillTexturedRectangle(*_f, &*_imageProgram, bufferOffset); FillTexturedRectangle(*_f, &*_imageProgram, bufferOffset);
} }

@ -1 +1 @@
Subproject commit 27e9e349bf6c817f13f1989e12cd3df7041c0bdc Subproject commit 4837b476234632ed1b7adf3c645d00d651381809