Track tiles visibility separately from geometry.

This commit is contained in:
John Preston 2021-05-31 18:40:41 +04:00
parent b3c92ed3f4
commit b22363224f
5 changed files with 35 additions and 14 deletions

View file

@ -175,7 +175,9 @@ void Viewport::updateSelected(QPoint position) {
return;
}
for (const auto &tile : _tiles) {
const auto geometry = tile->geometry();
const auto geometry = tile->shown()
? tile->geometry()
: QRect();
if (geometry.contains(position)) {
const auto pin = wide()
&& tile->pinOuter().contains(position - geometry.topLeft());
@ -215,7 +217,9 @@ void Viewport::add(
[=] { widget()->update(); }));
_tiles.back()->trackSizeValue(
) | rpl::start_with_next([=] {
) | rpl::filter([](QSize size) {
return !size.isEmpty();
}) | rpl::start_with_next([=] {
updateTilesGeometry();
}, _tiles.back()->lifetime());
}
@ -427,7 +431,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) {
const auto video = tile.get();
const auto size = video->trackSize();
if (size.isEmpty()) {
video->setGeometry({ 0, y, outerWidth, 0 });
setTileGeometry(video, { 0, y, outerWidth, 0 });
} else {
sizes.emplace(video, size);
}
@ -444,7 +448,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) {
Qt::KeepAspectRatio);
const auto height = std::max(scaled.height(), heightMin);
const auto skip = st::groupCallVideoSmallSkip;
sizes.front().first->setGeometry({ 0, y, outerWidth, height });
setTileGeometry(sizes.front().first, { 0, y, outerWidth, height });
_fullHeight = height + skip;
return;
}
@ -455,7 +459,7 @@ void Viewport::updateTilesGeometryNarrow(int outerWidth) {
const auto square = (outerWidth - st::groupCallVideoSmallSkip) / 2;
const auto skip = (outerWidth - 2 * square);
const auto put = [&](not_null<VideoTile*> tile, int column, int row) {
tile->setGeometry({
setTileGeometry(tile, {
(column == 2) ? 0 : column ? (outerWidth - square) : 0,
y + row * (min + skip),
(column == 2) ? outerWidth : square,
@ -492,7 +496,7 @@ void Viewport::updateTilesGeometryColumn(int outerWidth) {
const auto height = shown
? st::groupCallNarrowVideoHeight
: 0;
tile->setGeometry({ 0, y + top, outerWidth, height });
setTileGeometry(tile, { 0, y + top, outerWidth, height });
top += height ? (height + st::groupCallVideoSmallSkip) : 0;
};
const auto topPeer = _large ? _large->row()->peer().get() : nullptr;
@ -532,6 +536,7 @@ void Viewport::updateTilesGeometryColumn(int outerWidth) {
void Viewport::setTileGeometry(not_null<VideoTile*> tile, QRect geometry) {
tile->setGeometry(geometry);
tile->setShown(!geometry.isEmpty());
const auto min = std::min(geometry.width(), geometry.height());
const auto kMedium = style::ConvertScale(480);

View file

@ -383,6 +383,9 @@ void Viewport::RendererGL::paint(
const auto defaultFramebufferObject = widget->defaultFramebufferObject();
auto index = 0;
for (const auto &tile : _owner->_tiles) {
if (!tile->shown()) {
continue;
}
paintTile(
f,
defaultFramebufferObject,
@ -396,7 +399,9 @@ void Viewport::RendererGL::fillBackground(QOpenGLFunctions &f) {
const auto radiuses = QMargins{ radius, radius, radius, radius };
auto bg = QRegion(QRect(QPoint(), _viewport));
for (const auto &tile : _owner->_tiles) {
bg -= tile->geometry().marginsRemoved(radiuses);
if (tile->shown()) {
bg -= tile->geometry().marginsRemoved(radiuses);
}
}
if (bg.isEmpty()) {
return;
@ -427,12 +432,9 @@ void Viewport::RendererGL::paintTile(
return;
}
Assert(!data.yuv420->size.isEmpty());
const auto geometry = tile->geometry();
if (geometry.isEmpty()) {
return;
}
_rgbaFrame = (data.format == Webrtc::FrameFormat::ARGB32);
const auto geometry = tile->geometry();
const auto x = geometry.x();
const auto y = geometry.y();
const auto width = geometry.width();
@ -1019,9 +1021,15 @@ void Viewport::RendererGL::validateDatas() {
- st.iconPosition.x()
- st::groupCallVideoCrossLine.icon.width()
- st.namePosition.x();
if (hasWidth < 1) {
return 0;
}
return std::clamp(row->name().maxWidth(), 1, hasWidth) * factor;
};
for (auto i = 0; i != count; ++i) {
if (!tiles[i]->shown()) {
continue;
}
tiles[i]->row()->lazyInitialize(st::groupCallMembersListItem);
const auto width = nameWidth(i);
if (width <= 0) {

View file

@ -54,7 +54,7 @@ void Viewport::Renderer::paintTile(
const auto data = track->frameWithInfo(true);
const auto &image = data.original;
const auto rotation = data.rotation;
if (image.isNull()) {
if (image.isNull() || !tile->shown()) {
return;
}
@ -150,7 +150,6 @@ void Viewport::Renderer::paintTileControls(
const auto wide = _owner->wide();
if (wide) {
// Pin.
const auto pinInner = tile->pinInner();
VideoTile::PaintPinButton(
p,

View file

@ -63,6 +63,10 @@ void Viewport::VideoTile::setGeometry(QRect geometry) {
updateTopControlsGeometry();
}
void Viewport::VideoTile::setShown(bool shown) {
_shown = shown;
}
void Viewport::VideoTile::toggleTopControlsShown(bool shown) {
if (_topControlsShown == shown) {
return;
@ -76,7 +80,7 @@ void Viewport::VideoTile::toggleTopControlsShown(bool shown) {
}
bool Viewport::VideoTile::updateRequestedQuality(VideoQuality quality) {
if (_geometry.isEmpty()) {
if (!_shown) {
_quality = std::nullopt;
return false;
} else if (_quality && *_quality == quality) {

View file

@ -41,6 +41,9 @@ public:
[[nodiscard]] bool pinned() const {
return _pinned;
}
[[nodiscard]] bool shown() const {
return _shown && !_geometry.isEmpty();
}
[[nodiscard]] QRect pinOuter() const;
[[nodiscard]] QRect pinInner() const;
[[nodiscard]] QRect backOuter() const;
@ -57,6 +60,7 @@ public:
[[nodiscard]] bool screencast() const;
void setGeometry(QRect geometry);
void setShown(bool shown);
void toggleTopControlsShown(bool shown);
bool updateRequestedQuality(VideoQuality quality);
@ -100,6 +104,7 @@ private:
Ui::Animations::Simple _topControlsShownAnimation;
bool _topControlsShown = false;
bool _pinned = false;
bool _shown = false;
std::optional<VideoQuality> _quality;
rpl::lifetime _lifetime;