mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Round outgoing video preview.
This commit is contained in:
parent
4971e281fa
commit
38546c701a
3 changed files with 59 additions and 6 deletions
|
@ -34,7 +34,7 @@ callShadow: Shadow {
|
||||||
|
|
||||||
callWidthMin: 380px;
|
callWidthMin: 380px;
|
||||||
callHeightMin: 440px;
|
callHeightMin: 440px;
|
||||||
callWidth: 960px;
|
callWidth: 720px;
|
||||||
callHeight: 540px;
|
callHeight: 540px;
|
||||||
|
|
||||||
callBottomControlsHeight: 85px;
|
callBottomControlsHeight: 85px;
|
||||||
|
|
|
@ -9,7 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "webrtc/webrtc_video_track.h"
|
#include "webrtc/webrtc_video_track.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
|
||||||
namespace Calls {
|
namespace Calls {
|
||||||
|
|
||||||
|
@ -110,11 +113,58 @@ void VideoBubble::applySizeConstraints(QSize min, QSize max) {
|
||||||
void VideoBubble::paint() {
|
void VideoBubble::paint() {
|
||||||
Painter p(&_content);
|
Painter p(&_content);
|
||||||
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
prepareFrame();
|
||||||
p.drawImage(_content.rect(), _track->frame({}));
|
if (!_frame.isNull()) {
|
||||||
|
const auto padding = st::boxRoundShadow.extend;
|
||||||
|
const auto inner = _content.rect().marginsRemoved(padding);
|
||||||
|
Ui::Shadow::paint(p, inner, _content.width(), st::boxRoundShadow);
|
||||||
|
p.drawImage(
|
||||||
|
inner,
|
||||||
|
_frame,
|
||||||
|
QRect(QPoint(), inner.size() * cIntRetinaFactor()));
|
||||||
|
}
|
||||||
_track->markFrameShown();
|
_track->markFrameShown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoBubble::prepareFrame() {
|
||||||
|
const auto original = _track->frameSize();
|
||||||
|
if (original.isEmpty()) {
|
||||||
|
_frame = QImage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto padding = st::boxRoundShadow.extend;
|
||||||
|
const auto size = _content.rect().marginsRemoved(padding).size()
|
||||||
|
* cIntRetinaFactor();
|
||||||
|
|
||||||
|
// Should we check 'original' and 'size' aspect ratios?..
|
||||||
|
const auto request = webrtc::FrameRequest{
|
||||||
|
.resize = size,
|
||||||
|
.outer = size,
|
||||||
|
};
|
||||||
|
const auto frame = _track->frame(request);
|
||||||
|
if (_frame.width() < size.width() || _frame.height() < size.height()) {
|
||||||
|
_frame = QImage(
|
||||||
|
_max * cIntRetinaFactor(),
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
}
|
||||||
|
Assert(_frame.width() >= frame.width()
|
||||||
|
&& _frame.height() >= frame.height());
|
||||||
|
const auto toPerLine = _frame.bytesPerLine();
|
||||||
|
const auto fromPerLine = frame.bytesPerLine();
|
||||||
|
const auto lineSize = frame.width() * 4;
|
||||||
|
auto to = _frame.bits();
|
||||||
|
auto from = frame.bits();
|
||||||
|
const auto till = from + frame.height() * fromPerLine;
|
||||||
|
for (; from != till; from += fromPerLine, to += toPerLine) {
|
||||||
|
memcpy(to, from, lineSize);
|
||||||
|
}
|
||||||
|
Images::prepareRound(
|
||||||
|
_frame,
|
||||||
|
ImageRoundRadius::Large,
|
||||||
|
RectPart::AllCorners,
|
||||||
|
QRect(QPoint(), size));
|
||||||
|
}
|
||||||
|
|
||||||
void VideoBubble::setState(webrtc::VideoState state) {
|
void VideoBubble::setState(webrtc::VideoState state) {
|
||||||
if (state == webrtc::VideoState::Paused) {
|
if (state == webrtc::VideoState::Paused) {
|
||||||
using namespace Images;
|
using namespace Images;
|
||||||
|
@ -161,7 +211,7 @@ void VideoBubble::setInnerSize(QSize size) {
|
||||||
}
|
}
|
||||||
_geometryDirty = false;
|
_geometryDirty = false;
|
||||||
_size = size;
|
_size = size;
|
||||||
_content.setGeometry(QRect([&] {
|
const auto topLeft = [&] {
|
||||||
switch (_corner) {
|
switch (_corner) {
|
||||||
case RectPart::None:
|
case RectPart::None:
|
||||||
return _boundingRect.topLeft() + QPoint(
|
return _boundingRect.topLeft() + QPoint(
|
||||||
|
@ -183,7 +233,9 @@ void VideoBubble::setInnerSize(QSize size) {
|
||||||
_boundingRect.y() + _boundingRect.height() - size.height());
|
_boundingRect.y() + _boundingRect.height() - size.height());
|
||||||
}
|
}
|
||||||
Unexpected("Corner value in VideoBubble::setInnerSize.");
|
Unexpected("Corner value in VideoBubble::setInnerSize.");
|
||||||
}(), size));
|
}();
|
||||||
|
const auto inner = QRect(topLeft, size);
|
||||||
|
_content.setGeometry(inner.marginsAdded(st::boxRoundShadow.extend));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBubble::updateVisibility() {
|
void VideoBubble::updateVisibility() {
|
||||||
|
|
|
@ -46,11 +46,12 @@ private:
|
||||||
void updateSizeToFrame(QSize frame);
|
void updateSizeToFrame(QSize frame);
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
void setInnerSize(QSize size);
|
void setInnerSize(QSize size);
|
||||||
|
void prepareFrame();
|
||||||
|
|
||||||
Ui::RpWidget _content;
|
Ui::RpWidget _content;
|
||||||
const not_null<webrtc::VideoTrack*> _track;
|
const not_null<webrtc::VideoTrack*> _track;
|
||||||
webrtc::VideoState _state = webrtc::VideoState();
|
webrtc::VideoState _state = webrtc::VideoState();
|
||||||
QImage _pausedFrame;
|
QImage _frame, _pausedFrame;
|
||||||
QSize _min, _max, _size, _lastDraggableSize, _lastFrameSize;
|
QSize _min, _max, _size, _lastDraggableSize, _lastFrameSize;
|
||||||
QRect _boundingRect;
|
QRect _boundingRect;
|
||||||
DragMode _dragMode = DragMode::None;
|
DragMode _dragMode = DragMode::None;
|
||||||
|
|
Loading…
Add table
Reference in a new issue