mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Use Ui::Window for the Calls::Panel.
This commit is contained in:
parent
79feb0c6d9
commit
38b9111bf5
8 changed files with 230 additions and 342 deletions
|
@ -259,3 +259,80 @@ callBarSignalBars: CallSignalBars(callPanelSignalBars) {
|
||||||
}
|
}
|
||||||
callSignalMargin: 8px;
|
callSignalMargin: 8px;
|
||||||
callSignalPadding: 4px;
|
callSignalPadding: 4px;
|
||||||
|
|
||||||
|
callTitle: WindowTitle(defaultWindowTitle) {
|
||||||
|
bg: callBgOpaque;
|
||||||
|
bgActive: callBgOpaque;
|
||||||
|
fg: transparent;
|
||||||
|
fgActive: transparent;
|
||||||
|
minimize: IconButton(windowTitleButton) {
|
||||||
|
icon: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_minimize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
iconOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_minimize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
minimizeIconActive: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_minimize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
minimizeIconActiveOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_minimize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
maximize: IconButton(windowTitleButton) {
|
||||||
|
icon: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_maximize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
iconOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_maximize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
maximizeIconActive: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_maximize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
maximizeIconActiveOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_maximize", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
restoreIcon: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_restore", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
restoreIconOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_restore", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
restoreIconActive: icon {
|
||||||
|
{ size(24px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_restore", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
restoreIconActiveOver: icon {
|
||||||
|
{ size(24px, 21px), callMuteRipple },
|
||||||
|
{ "title_button_restore", callStatusFg, point(4px, 4px) },
|
||||||
|
};
|
||||||
|
close: IconButton(windowTitleButtonClose) {
|
||||||
|
icon: icon {
|
||||||
|
{ size(25px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_close", callStatusFg, point(5px, 4px) },
|
||||||
|
};
|
||||||
|
iconOver: icon {
|
||||||
|
{ size(25px, 21px), titleButtonCloseBgOver },
|
||||||
|
{ "title_button_close", titleButtonCloseFgOver, point(5px, 4px) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
closeIconActive: icon {
|
||||||
|
{ size(25px, 21px), callBgOpaque },
|
||||||
|
{ "title_button_close", callStatusFg, point(5px, 4px) },
|
||||||
|
};
|
||||||
|
closeIconActiveOver: icon {
|
||||||
|
{ size(25px, 21px), titleButtonCloseBgActiveOver },
|
||||||
|
{ "title_button_close", titleButtonCloseFgActiveOver, point(5px, 4px) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -35,13 +35,7 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * crl::time(1000);
|
||||||
|
|
||||||
Instance::Instance() = default;
|
Instance::Instance() = default;
|
||||||
|
|
||||||
Instance::~Instance() {
|
Instance::~Instance() = default;
|
||||||
for (const auto panel : _pendingPanels) {
|
|
||||||
if (panel) {
|
|
||||||
delete panel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
|
void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
|
||||||
if (alreadyInCall()) { // Already in a call.
|
if (alreadyInCall()) { // Already in a call.
|
||||||
|
@ -120,14 +114,10 @@ void Instance::destroyCall(not_null<Call*> call) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::destroyCurrentPanel() {
|
void Instance::destroyCurrentPanel() {
|
||||||
_pendingPanels.erase(
|
_currentCallPanel->hideBeforeDestroy();
|
||||||
std::remove_if(
|
|
||||||
_pendingPanels.begin(),
|
// Always queue the destruction.
|
||||||
_pendingPanels.end(),
|
crl::on_main([panel = std::move(_currentCallPanel)]{});
|
||||||
[](auto &&panel) { return !panel; }),
|
|
||||||
_pendingPanels.end());
|
|
||||||
_pendingPanels.emplace_back(_currentCallPanel.release());
|
|
||||||
_pendingPanels.back()->hideAndDestroy(); // Always queues the destruction.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::createCall(not_null<UserData*> user, Call::Type type, bool video) {
|
void Instance::createCall(not_null<UserData*> user, Call::Type type, bool video) {
|
||||||
|
|
|
@ -85,7 +85,6 @@ private:
|
||||||
std::unique_ptr<Panel> _currentCallPanel;
|
std::unique_ptr<Panel> _currentCallPanel;
|
||||||
base::Observable<Call*> _currentCallChanged;
|
base::Observable<Call*> _currentCallChanged;
|
||||||
base::Observable<FullMsgId> _newServiceMessage;
|
base::Observable<FullMsgId> _newServiceMessage;
|
||||||
std::vector<QPointer<Panel>> _pendingPanels;
|
|
||||||
|
|
||||||
std::unique_ptr<Media::Audio::Track> _callConnectingTrack;
|
std::unique_ptr<Media::Audio::Track> _callConnectingTrack;
|
||||||
std::unique_ptr<Media::Audio::Track> _callEndedTrack;
|
std::unique_ptr<Media::Audio::Track> _callEndedTrack;
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/widgets/window.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
@ -50,7 +51,7 @@ constexpr auto kTooltipShowTimeoutMs = 1000;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class Panel::Button : public Ui::RippleButton {
|
class Panel::Button final : public Ui::RippleButton {
|
||||||
public:
|
public:
|
||||||
Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo = nullptr);
|
Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo = nullptr);
|
||||||
|
|
||||||
|
@ -86,7 +87,8 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo) : Ui::RippleButton(parent, stFrom.button.ripple)
|
Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo)
|
||||||
|
: Ui::RippleButton(parent, stFrom.button.ripple)
|
||||||
, _stFrom(&stFrom)
|
, _stFrom(&stFrom)
|
||||||
, _stTo(stTo) {
|
, _stTo(stTo) {
|
||||||
resize(_stFrom->button.width, _stFrom->button.height);
|
resize(_stFrom->button.width, _stFrom->button.height);
|
||||||
|
@ -255,22 +257,22 @@ QImage Panel::Button::prepareRippleMask() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel::Panel(not_null<Call*> call)
|
Panel::Panel(not_null<Call*> call)
|
||||||
: RpWidget(Core::App().getModalParent())
|
: _call(call)
|
||||||
, _call(call)
|
|
||||||
, _user(call->user())
|
, _user(call->user())
|
||||||
|
, _window(std::make_unique<Ui::Window>(Core::App().getModalParent()))
|
||||||
, _bodySt(&st::callBodyLayout)
|
, _bodySt(&st::callBodyLayout)
|
||||||
, _answerHangupRedial(this, st::callAnswer, &st::callHangup)
|
, _answerHangupRedial(widget(), st::callAnswer, &st::callHangup)
|
||||||
, _decline(this, object_ptr<Button>(this, st::callHangup))
|
, _decline(widget(), object_ptr<Button>(widget(), st::callHangup))
|
||||||
, _cancel(this, object_ptr<Button>(this, st::callCancel))
|
, _cancel(widget(), object_ptr<Button>(widget(), st::callCancel))
|
||||||
, _camera(this, st::callCameraToggle)
|
, _camera(widget(), st::callCameraToggle)
|
||||||
, _mute(this, st::callMuteToggle)
|
, _mute(widget(), st::callMuteToggle)
|
||||||
, _name(this, st::callName)
|
, _name(widget(), st::callName)
|
||||||
, _status(this, st::callStatus) {
|
, _status(widget(), st::callStatus) {
|
||||||
_decline->setDuration(st::callPanelDuration);
|
_decline->setDuration(st::callPanelDuration);
|
||||||
_cancel->setDuration(st::callPanelDuration);
|
_cancel->setDuration(st::callPanelDuration);
|
||||||
|
|
||||||
setMouseTracking(true);
|
initWindow();
|
||||||
setWindowIcon(Window::CreateIcon(&_user->session()));
|
initWidget();
|
||||||
initControls();
|
initControls();
|
||||||
initLayout();
|
initLayout();
|
||||||
showAndActivate();
|
showAndActivate();
|
||||||
|
@ -279,11 +281,10 @@ Panel::Panel(not_null<Call*> call)
|
||||||
Panel::~Panel() = default;
|
Panel::~Panel() = default;
|
||||||
|
|
||||||
void Panel::showAndActivate() {
|
void Panel::showAndActivate() {
|
||||||
toggleOpacityAnimation(true);
|
_window->raise();
|
||||||
raise();
|
_window->setWindowState(_window->windowState() | Qt::WindowActive);
|
||||||
setWindowState(windowState() | Qt::WindowActive);
|
_window->activateWindow();
|
||||||
activateWindow();
|
_window->setFocus();
|
||||||
setFocus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::replaceCall(not_null<Call*> call) {
|
void Panel::replaceCall(not_null<Call*> call) {
|
||||||
|
@ -291,15 +292,47 @@ void Panel::replaceCall(not_null<Call*> call) {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Panel::eventHook(QEvent *e) {
|
void Panel::initWindow() {
|
||||||
if (e->type() == QEvent::WindowDeactivate) {
|
_window->setWindowIcon(
|
||||||
checkForInactiveHide();
|
QIcon(QPixmap::fromImage(Image::Empty()->original(), Qt::ColorOnly)));
|
||||||
}
|
_window->setTitle(u" "_q);
|
||||||
return RpWidget::eventHook(e);
|
|
||||||
|
_window->events(
|
||||||
|
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||||
|
if (e->type() == QEvent::Close) {
|
||||||
|
handleClose();
|
||||||
|
}
|
||||||
|
}, _window->lifetime());
|
||||||
|
|
||||||
|
_window->setBodyTitleArea([=](QPoint widgetPoint) {
|
||||||
|
const auto buttonWidth = st::callCancel.button.width;
|
||||||
|
const auto buttonsWidth = buttonWidth * 4;
|
||||||
|
return !_fingerprintArea.contains(widgetPoint)
|
||||||
|
&& !QRect(
|
||||||
|
(widget()->width() - buttonsWidth) / 2,
|
||||||
|
_answerHangupRedial->y(),
|
||||||
|
buttonsWidth,
|
||||||
|
_answerHangupRedial->height()).contains(widgetPoint)
|
||||||
|
&& !_outgoingVideoBubble->geometry().contains(widgetPoint);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::hideDeactivated() {
|
void Panel::initWidget() {
|
||||||
toggleOpacityAnimation(false);
|
widget()->setMouseTracking(true);
|
||||||
|
|
||||||
|
widget()->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
paint(clip);
|
||||||
|
}, widget()->lifetime());
|
||||||
|
|
||||||
|
widget()->events(
|
||||||
|
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||||
|
if (e->type() == QEvent::MouseMove) {
|
||||||
|
handleMouseMove(static_cast<QMouseEvent*>(e.get()));
|
||||||
|
} else if (e->type() == QEvent::Resize) {
|
||||||
|
updateControlsGeometry();
|
||||||
|
}
|
||||||
|
}, widget()->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::initControls() {
|
void Panel::initControls() {
|
||||||
|
@ -363,9 +396,7 @@ void Panel::setIncomingShown(bool shown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_incomingShown = shown;
|
_incomingShown = shown;
|
||||||
if (_animationCache.isNull()) {
|
showControls();
|
||||||
showControls();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::reinitWithCall(Call *call) {
|
void Panel::reinitWithCall(Call *call) {
|
||||||
|
@ -379,18 +410,21 @@ void Panel::reinitWithCall(Call *call) {
|
||||||
_user = _call->user();
|
_user = _call->user();
|
||||||
|
|
||||||
_signalBars.create(
|
_signalBars.create(
|
||||||
this,
|
widget(),
|
||||||
_call,
|
_call,
|
||||||
st::callPanelSignalBars,
|
st::callPanelSignalBars,
|
||||||
[=] { rtlupdate(signalBarsRect()); });
|
[=] { widget()->rtlupdate(signalBarsRect()); });
|
||||||
|
|
||||||
auto remoteMuted = _call->remoteAudioStateValue(
|
auto remoteMuted = _call->remoteAudioStateValue(
|
||||||
) | rpl::map([=](Call::RemoteAudioState state) {
|
) | rpl::map([=](Call::RemoteAudioState state) {
|
||||||
return (state == Call::RemoteAudioState::Muted);
|
return (state == Call::RemoteAudioState::Muted);
|
||||||
});
|
});
|
||||||
_userpic = std::make_unique<Userpic>(this, _user, std::move(remoteMuted));
|
_userpic = std::make_unique<Userpic>(
|
||||||
|
widget(),
|
||||||
|
_user,
|
||||||
|
std::move(remoteMuted));
|
||||||
_outgoingVideoBubble = std::make_unique<VideoBubble>(
|
_outgoingVideoBubble = std::make_unique<VideoBubble>(
|
||||||
this,
|
widget(),
|
||||||
_call->videoOutgoing());
|
_call->videoOutgoing());
|
||||||
|
|
||||||
_call->mutedValue(
|
_call->mutedValue(
|
||||||
|
@ -413,14 +447,7 @@ void Panel::reinitWithCall(Call *call) {
|
||||||
_call->videoIncoming()->renderNextFrame(
|
_call->videoIncoming()->renderNextFrame(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
setIncomingShown(!_call->videoIncoming()->frame({}).isNull());
|
setIncomingShown(!_call->videoIncoming()->frame({}).isNull());
|
||||||
update();
|
widget()->update();
|
||||||
}, _callLifetime);
|
|
||||||
|
|
||||||
rpl::merge(
|
|
||||||
_call->videoIncoming()->stateChanges(),
|
|
||||||
_call->videoOutgoing()->stateChanges()
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
checkForInactiveShow();
|
|
||||||
}, _callLifetime);
|
}, _callLifetime);
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
|
@ -441,11 +468,6 @@ void Panel::reinitWithCall(Call *call) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::initLayout() {
|
void Panel::initLayout() {
|
||||||
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::NoDropShadowWindowHint | Qt::Dialog);
|
|
||||||
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
|
||||||
setAttribute(Qt::WA_TranslucentBackground);
|
|
||||||
|
|
||||||
initGeometry();
|
initGeometry();
|
||||||
|
|
||||||
using UpdateFlag = Data::PeerUpdate::Flag;
|
using UpdateFlag = Data::PeerUpdate::Flag;
|
||||||
|
@ -457,56 +479,13 @@ void Panel::initLayout() {
|
||||||
}) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
}) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||||
_name->setText(_call->user()->name);
|
_name->setText(_call->user()->name);
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}, lifetime());
|
}, widget()->lifetime());
|
||||||
|
|
||||||
createDefaultCacheImage();
|
|
||||||
|
|
||||||
Ui::Platform::InitOnTopPanel(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::toggleOpacityAnimation(bool visible) {
|
|
||||||
if (!_call || _visible == visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_visible = visible;
|
|
||||||
if (_useTransparency) {
|
|
||||||
if (_animationCache.isNull()) {
|
|
||||||
showControls();
|
|
||||||
_animationCache = Ui::GrabWidget(this);
|
|
||||||
hideChildren();
|
|
||||||
}
|
|
||||||
_opacityAnimation.start(
|
|
||||||
[this] { update(); },
|
|
||||||
_visible ? 0. : 1.,
|
|
||||||
_visible ? 1. : 0.,
|
|
||||||
st::callPanelDuration,
|
|
||||||
_visible ? anim::easeOutCirc : anim::easeInCirc);
|
|
||||||
} else if (!isHidden() && !_visible) {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
if (isHidden() && _visible) {
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::finishAnimating() {
|
|
||||||
_animationCache = QPixmap();
|
|
||||||
if (_call) {
|
|
||||||
if (!_visible) {
|
|
||||||
hide();
|
|
||||||
} else {
|
|
||||||
showControls();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
destroyDelayed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::showControls() {
|
void Panel::showControls() {
|
||||||
Expects(_call != nullptr);
|
Expects(_call != nullptr);
|
||||||
|
|
||||||
showChildren();
|
widget()->showChildren();
|
||||||
_decline->setVisible(_decline->toggled());
|
_decline->setVisible(_decline->toggled());
|
||||||
_cancel->setVisible(_cancel->toggled());
|
_cancel->setVisible(_cancel->toggled());
|
||||||
_name->setVisible(!_incomingShown);
|
_name->setVisible(!_incomingShown);
|
||||||
|
@ -514,34 +493,18 @@ void Panel::showControls() {
|
||||||
_userpic->setVisible(!_incomingShown);
|
_userpic->setVisible(!_incomingShown);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::destroyDelayed() {
|
void Panel::hideBeforeDestroy() {
|
||||||
hide();
|
_window->hide();
|
||||||
crl::on_main(this, [=] {
|
|
||||||
delete this;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::hideAndDestroy() {
|
|
||||||
toggleOpacityAnimation(false);
|
|
||||||
reinitWithCall(nullptr);
|
reinitWithCall(nullptr);
|
||||||
if (_animationCache.isNull()) {
|
|
||||||
destroyDelayed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::initGeometry() {
|
void Panel::initGeometry() {
|
||||||
const auto center = Core::App().getPointForCallPanelCenter();
|
const auto center = Core::App().getPointForCallPanelCenter();
|
||||||
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
|
const auto initRect = QRect(0, 0, st::callWidth, st::callHeight);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
_window->setGeometry(initRect.translated(center - initRect.center()));
|
||||||
_padding = _useTransparency ? st::callShadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
|
_window->setMinimumSize({ st::callWidthMin, st::callHeightMin });
|
||||||
const auto rect = [&] {
|
_window->setTitleStyle(st::callTitle);
|
||||||
const QRect initRect(0, 0, st::callWidth, st::callHeight);
|
_window->show();
|
||||||
return initRect.translated(center - initRect.center()).marginsAdded(_padding);
|
|
||||||
}();
|
|
||||||
setGeometry(rect);
|
|
||||||
setMinimumSize(rect.size());
|
|
||||||
setMaximumSize(rect.size());
|
|
||||||
createBottomImage();
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,56 +520,32 @@ void Panel::refreshOutgoingPreviewInBody(State state) {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::createBottomImage() {
|
void Panel::updateFingerprintGeometry() {
|
||||||
if (!_useTransparency) {
|
auto realSize = Ui::Emoji::GetSizeLarge();
|
||||||
return;
|
auto size = realSize / cIntRetinaFactor();
|
||||||
}
|
auto count = _fingerprint.size();
|
||||||
auto bottomWidth = width();
|
auto rectWidth = count * size + (count - 1) * st::callFingerprintSkip;
|
||||||
auto bottomHeight = height();
|
auto rectHeight = size;
|
||||||
auto image = QImage(QSize(bottomWidth, bottomHeight) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
auto left = (widget()->width() - rectWidth) / 2;
|
||||||
const auto inner = rect().marginsRemoved(_padding);
|
_fingerprintArea = QRect(
|
||||||
image.fill(Qt::transparent);
|
left,
|
||||||
{
|
st::callFingerprintTop + st::callFingerprintPadding.top(),
|
||||||
Painter p(&image);
|
rectWidth,
|
||||||
Ui::Shadow::paint(p, inner, width(), st::callShadow);
|
rectHeight
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
).marginsAdded(st::callFingerprintPadding);
|
||||||
p.setBrush(st::callBg);
|
_fingerprintHeight = st::callFingerprintTop + _fingerprintArea.height() + st::callFingerprintBottom;
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
p.drawRoundedRect(inner, st::callRadius, st::callRadius);
|
|
||||||
}
|
|
||||||
_bottomCache = App::pixmapFromImageInPlace(std::move(image));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::createDefaultCacheImage() {
|
|
||||||
if (!_useTransparency || !_cache.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto cache = QImage(size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
|
||||||
cache.setDevicePixelRatio(cRetinaFactor());
|
|
||||||
cache.fill(Qt::transparent);
|
|
||||||
{
|
|
||||||
Painter p(&cache);
|
|
||||||
auto inner = rect().marginsRemoved(_padding);
|
|
||||||
Ui::Shadow::paint(p, inner, width(), st::callShadow);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
p.setBrush(st::callBg);
|
|
||||||
p.setPen(Qt::NoPen);
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
p.drawRoundedRect(myrtlrect(inner), st::callRadius, st::callRadius);
|
|
||||||
}
|
|
||||||
_cache = App::pixmapFromImageInPlace(std::move(cache));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::resizeEvent(QResizeEvent *e) {
|
|
||||||
updateControlsGeometry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateControlsGeometry() {
|
void Panel::updateControlsGeometry() {
|
||||||
const auto innerHeight = height() - _padding.top() - _padding.bottom();
|
if (widget()->width() < st::callWidthMin
|
||||||
const auto availableTop = _padding.top() + _fingerprintHeight;
|
|| widget()->height() < st::callHeightMin) {
|
||||||
const auto available = height()
|
return;
|
||||||
- (st::callBottomControlsHeight + _padding.bottom())
|
}
|
||||||
|
updateFingerprintGeometry();
|
||||||
|
const auto innerHeight = widget()->height();
|
||||||
|
const auto availableTop = _fingerprintHeight;
|
||||||
|
const auto available = widget()->height()
|
||||||
|
- st::callBottomControlsHeight
|
||||||
- availableTop;
|
- availableTop;
|
||||||
const auto bodyPreviewSizeMax = st::callOutgoingPreviewMin
|
const auto bodyPreviewSizeMax = st::callOutgoingPreviewMin
|
||||||
+ ((st::callOutgoingPreview
|
+ ((st::callOutgoingPreview
|
||||||
|
@ -627,12 +566,12 @@ void Panel::updateControlsGeometry() {
|
||||||
const auto previewTop = _bodyTop + _bodySt->height + skipHeight;
|
const auto previewTop = _bodyTop + _bodySt->height + skipHeight;
|
||||||
|
|
||||||
_userpic->setGeometry(
|
_userpic->setGeometry(
|
||||||
(width() - _bodySt->photoSize) / 2,
|
(widget()->width() - _bodySt->photoSize) / 2,
|
||||||
_bodyTop + _bodySt->photoTop,
|
_bodyTop + _bodySt->photoTop,
|
||||||
_bodySt->photoSize);
|
_bodySt->photoSize);
|
||||||
|
|
||||||
_name->moveToLeft(
|
_name->moveToLeft(
|
||||||
(width() - _name->width()) / 2,
|
(widget()->width() - _name->width()) / 2,
|
||||||
_bodyTop + _bodySt->nameTop);
|
_bodyTop + _bodySt->nameTop);
|
||||||
updateStatusGeometry();
|
updateStatusGeometry();
|
||||||
|
|
||||||
|
@ -640,7 +579,7 @@ void Panel::updateControlsGeometry() {
|
||||||
_outgoingVideoBubble->updateGeometry(
|
_outgoingVideoBubble->updateGeometry(
|
||||||
VideoBubble::DragMode::None,
|
VideoBubble::DragMode::None,
|
||||||
QRect(
|
QRect(
|
||||||
(width() - bodyPreviewSize.width()) / 2,
|
(widget()->width() - bodyPreviewSize.width()) / 2,
|
||||||
previewTop,
|
previewTop,
|
||||||
bodyPreviewSize.width(),
|
bodyPreviewSize.width(),
|
||||||
bodyPreviewSize.height()));
|
bodyPreviewSize.height()));
|
||||||
|
@ -649,39 +588,31 @@ void Panel::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bothWidth = _answerHangupRedial->width() + st::callCancel.button.width;
|
auto bothWidth = _answerHangupRedial->width() + st::callCancel.button.width;
|
||||||
_decline->moveToLeft((width() - bothWidth) / 2, _buttonsTop);
|
_decline->moveToLeft((widget()->width() - bothWidth) / 2, _buttonsTop);
|
||||||
_cancel->moveToLeft((width() - bothWidth) / 2, _buttonsTop);
|
_cancel->moveToLeft((widget()->width() - bothWidth) / 2, _buttonsTop);
|
||||||
|
|
||||||
updateHangupGeometry();
|
updateHangupGeometry();
|
||||||
|
|
||||||
const auto skip = st::callSignalMargin + st::callSignalPadding;
|
const auto skip = st::callSignalMargin + st::callSignalPadding;
|
||||||
const auto delta = (_signalBars->width() - _signalBars->height());
|
const auto delta = (_signalBars->width() - _signalBars->height());
|
||||||
_signalBars->moveToLeft(
|
_signalBars->moveToLeft(skip, skip + delta / 2);
|
||||||
_padding.left() + skip,
|
|
||||||
_padding.top() + skip + delta / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateOutgoingVideoBubbleGeometry() {
|
void Panel::updateOutgoingVideoBubbleGeometry() {
|
||||||
Expects(!_outgoingPreviewInBody);
|
Expects(!_outgoingPreviewInBody);
|
||||||
|
|
||||||
const auto size = st::callOutgoingDefaultSize;
|
const auto size = st::callOutgoingDefaultSize;
|
||||||
const auto availableHeight = height() - st::callBottomControlsHeight;
|
|
||||||
const auto padding = 2 * _padding;
|
|
||||||
_outgoingVideoBubble->updateGeometry(
|
_outgoingVideoBubble->updateGeometry(
|
||||||
VideoBubble::DragMode::SnapToCorners,
|
VideoBubble::DragMode::SnapToCorners,
|
||||||
QRect(
|
widget()->rect(),
|
||||||
padding.left(),
|
|
||||||
padding.top(),
|
|
||||||
width() - padding.left() - padding.right(),
|
|
||||||
height() - padding.left() - padding.bottom()),
|
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateHangupGeometry() {
|
void Panel::updateHangupGeometry() {
|
||||||
auto singleWidth = _answerHangupRedial->width();
|
auto singleWidth = _answerHangupRedial->width();
|
||||||
auto bothWidth = singleWidth + st::callCancel.button.width;
|
auto bothWidth = singleWidth + st::callCancel.button.width;
|
||||||
auto rightFrom = (width() - bothWidth) / 2;
|
auto rightFrom = (widget()->width() - bothWidth) / 2;
|
||||||
auto rightTo = (width() - singleWidth) / 2;
|
auto rightTo = (widget()->width() - singleWidth) / 2;
|
||||||
auto hangupProgress = _hangupShownProgress.value(_hangupShown ? 1. : 0.);
|
auto hangupProgress = _hangupShownProgress.value(_hangupShown ? 1. : 0.);
|
||||||
auto hangupRight = anim::interpolate(rightFrom, rightTo, hangupProgress);
|
auto hangupRight = anim::interpolate(rightFrom, rightTo, hangupProgress);
|
||||||
_answerHangupRedial->moveToRight(hangupRight, _buttonsTop);
|
_answerHangupRedial->moveToRight(hangupRight, _buttonsTop);
|
||||||
|
@ -691,41 +622,21 @@ void Panel::updateHangupGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateStatusGeometry() {
|
void Panel::updateStatusGeometry() {
|
||||||
_status->moveToLeft((width() - _status->width()) / 2, _bodyTop + _bodySt->statusTop);
|
_status->moveToLeft(
|
||||||
|
(widget()->width() - _status->width()) / 2,
|
||||||
|
_bodyTop + _bodySt->statusTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::paintEvent(QPaintEvent *e) {
|
void Panel::paint(QRect clip) {
|
||||||
Painter p(this);
|
Painter p(widget());
|
||||||
if (!_animationCache.isNull()) {
|
|
||||||
auto opacity = _opacityAnimation.value(_call ? 1. : 0.);
|
|
||||||
if (!_opacityAnimation.animating()) {
|
|
||||||
finishAnimating();
|
|
||||||
if (!_call || isHidden()) return;
|
|
||||||
} else {
|
|
||||||
p.setOpacity(opacity);
|
|
||||||
|
|
||||||
PainterHighQualityEnabler hq(p);
|
p.fillRect(clip, st::callBgOpaque);
|
||||||
auto marginRatio = (1. - opacity) / 5;
|
|
||||||
auto marginWidth = qRound(width() * marginRatio);
|
|
||||||
auto marginHeight = qRound(height() * marginRatio);
|
|
||||||
p.drawPixmap(rect().marginsRemoved(QMargins(marginWidth, marginHeight, marginWidth, marginHeight)), _animationCache, QRect(QPoint(0, 0), _animationCache.size()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_useTransparency) {
|
|
||||||
p.drawPixmapLeft(0, 0, width(), _cache);
|
|
||||||
} else {
|
|
||||||
auto callBgOpaque = st::callBg->c;
|
|
||||||
callBgOpaque.setAlpha(255);
|
|
||||||
p.fillRect(rect(), QBrush(callBgOpaque));
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto incomingFrame = _call
|
const auto incomingFrame = _call
|
||||||
? _call->videoIncoming()->frame(Webrtc::FrameRequest())
|
? _call->videoIncoming()->frame(Webrtc::FrameRequest())
|
||||||
: QImage();
|
: QImage();
|
||||||
if (!incomingFrame.isNull()) {
|
if (!incomingFrame.isNull()) {
|
||||||
const auto to = rect().marginsRemoved(_padding);
|
const auto to = widget()->rect();
|
||||||
p.save();
|
p.save();
|
||||||
p.setClipRect(to);
|
p.setClipRect(to);
|
||||||
const auto big = incomingFrame.size().scaled(to.size(), Qt::KeepAspectRatio);
|
const auto big = incomingFrame.size().scaled(to.size(), Qt::KeepAspectRatio);
|
||||||
|
@ -759,8 +670,8 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
QRect Panel::signalBarsRect() const {
|
QRect Panel::signalBarsRect() const {
|
||||||
const auto size = 2 * st::callSignalPadding + _signalBars->width();
|
const auto size = 2 * st::callSignalPadding + _signalBars->width();
|
||||||
return QRect(
|
return QRect(
|
||||||
_padding.left() + st::callSignalMargin,
|
st::callSignalMargin,
|
||||||
_padding.top() + st::callSignalMargin,
|
st::callSignalMargin,
|
||||||
size,
|
size,
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
|
@ -773,50 +684,22 @@ void Panel::paintSignalBarsBg(Painter &p) {
|
||||||
ImageRoundRadius::Small);
|
ImageRoundRadius::Small);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::closeEvent(QCloseEvent *e) {
|
void Panel::handleClose() {
|
||||||
if (_call) {
|
if (_call) {
|
||||||
_call->hangup();
|
_call->hangup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::mousePressEvent(QMouseEvent *e) {
|
void Panel::handleMouseMove(not_null<QMouseEvent*> e) {
|
||||||
auto dragArea = myrtlrect(_padding.left(), _padding.top(), st::callWidth, st::callWidth);
|
if (_fingerprintArea.contains(e->pos())) {
|
||||||
if (e->button() == Qt::LeftButton) {
|
|
||||||
if (dragArea.contains(e->pos())) {
|
|
||||||
_dragging = true;
|
|
||||||
_dragStartMousePosition = e->globalPos();
|
|
||||||
_dragStartMyPosition = QPoint(x(), y());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::mouseMoveEvent(QMouseEvent *e) {
|
|
||||||
if (_dragging) {
|
|
||||||
Ui::Tooltip::Hide();
|
|
||||||
if (!(e->buttons() & Qt::LeftButton)) {
|
|
||||||
_dragging = false;
|
|
||||||
} else {
|
|
||||||
move(_dragStartMyPosition + (e->globalPos() - _dragStartMousePosition));
|
|
||||||
}
|
|
||||||
} else if (_fingerprintArea.contains(e->pos())) {
|
|
||||||
Ui::Tooltip::Show(kTooltipShowTimeoutMs, this);
|
Ui::Tooltip::Show(kTooltipShowTimeoutMs, this);
|
||||||
} else {
|
} else {
|
||||||
Ui::Tooltip::Hide();
|
Ui::Tooltip::Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::mouseReleaseEvent(QMouseEvent *e) {
|
not_null<Ui::RpWidget*> Panel::widget() const {
|
||||||
if (e->button() == Qt::LeftButton) {
|
return _window->body();
|
||||||
_dragging = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::leaveEventHook(QEvent *e) {
|
|
||||||
Ui::Tooltip::Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::leaveToChildEvent(QEvent *e, QWidget *child) {
|
|
||||||
Ui::Tooltip::Hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Panel::tooltipText() const {
|
QString Panel::tooltipText() const {
|
||||||
|
@ -828,7 +711,7 @@ QPoint Panel::tooltipPos() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Panel::tooltipWindowActive() const {
|
bool Panel::tooltipWindowActive() const {
|
||||||
return !isHidden();
|
return _window->isActiveWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::stateChanged(State state) {
|
void Panel::stateChanged(State state) {
|
||||||
|
@ -844,7 +727,7 @@ void Panel::stateChanged(State state) {
|
||||||
auto toggleButton = [this](auto &&button, bool visible) {
|
auto toggleButton = [this](auto &&button, bool visible) {
|
||||||
button->toggle(
|
button->toggle(
|
||||||
visible,
|
visible,
|
||||||
isHidden()
|
_window->isHidden()
|
||||||
? anim::type::instant
|
? anim::type::instant
|
||||||
: anim::type::normal);
|
: anim::type::normal);
|
||||||
};
|
};
|
||||||
|
@ -864,60 +747,14 @@ void Panel::stateChanged(State state) {
|
||||||
fillFingerprint();
|
fillFingerprint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (windowHandle()) {
|
|
||||||
// First stateChanged() is called before
|
|
||||||
// the first Platform::InitOnTopPanel(this).
|
|
||||||
if ((state == State::Starting) || (state == State::WaitingIncoming)) {
|
|
||||||
Ui::Platform::ReInitOnTopPanel(this);
|
|
||||||
} else {
|
|
||||||
Ui::Platform::DeInitOnTopPanel(this);
|
|
||||||
}
|
|
||||||
checkForInactiveHide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Panel::hasActiveVideo() const {
|
|
||||||
const auto inactive = Webrtc::VideoState::Inactive;
|
|
||||||
return (_call->videoIncoming()->state() != inactive)
|
|
||||||
|| (_call->videoOutgoing()->state() != inactive);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::checkForInactiveHide() {
|
|
||||||
if (!_call
|
|
||||||
|| (_call->state() != State::Established)
|
|
||||||
|| isActiveWindow()
|
|
||||||
|| hasActiveVideo()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hideDeactivated();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::checkForInactiveShow() {
|
|
||||||
if (!_visible && hasActiveVideo()) {
|
|
||||||
toggleOpacityAnimation(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::fillFingerprint() {
|
void Panel::fillFingerprint() {
|
||||||
Expects(_call != nullptr);
|
Expects(_call != nullptr);
|
||||||
|
|
||||||
_fingerprint = ComputeEmojiFingerprint(_call);
|
_fingerprint = ComputeEmojiFingerprint(_call);
|
||||||
|
|
||||||
auto realSize = Ui::Emoji::GetSizeLarge();
|
|
||||||
auto size = realSize / cIntRetinaFactor();
|
|
||||||
auto count = _fingerprint.size();
|
|
||||||
auto rectWidth = count * size + (count - 1) * st::callFingerprintSkip;
|
|
||||||
auto rectHeight = size;
|
|
||||||
auto left = (width() - rectWidth) / 2;
|
|
||||||
_fingerprintArea = QRect(
|
|
||||||
left,
|
|
||||||
_padding.top() + st::callFingerprintTop + st::callFingerprintPadding.top(),
|
|
||||||
rectWidth,
|
|
||||||
rectHeight
|
|
||||||
).marginsAdded(st::callFingerprintPadding);
|
|
||||||
_fingerprintHeight = st::callFingerprintTop + _fingerprintArea.height() + st::callFingerprintBottom;
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
widget()->update();
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateStatusText(State state) {
|
void Panel::updateStatusText(State state) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ class IconButton;
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
template <typename Widget>
|
template <typename Widget>
|
||||||
class FadeWrap;
|
class FadeWrap;
|
||||||
|
class Window;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
|
@ -39,48 +40,44 @@ class Userpic;
|
||||||
class SignalBars;
|
class SignalBars;
|
||||||
class VideoBubble;
|
class VideoBubble;
|
||||||
|
|
||||||
class Panel final : public Ui::RpWidget, private Ui::AbstractTooltipShower {
|
class Panel final : private Ui::AbstractTooltipShower {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Panel(not_null<Call*> call);
|
Panel(not_null<Call*> call);
|
||||||
~Panel();
|
~Panel();
|
||||||
|
|
||||||
void showAndActivate();
|
void showAndActivate();
|
||||||
void replaceCall(not_null<Call*> call);
|
void replaceCall(not_null<Call*> call);
|
||||||
void hideAndDestroy();
|
void hideBeforeDestroy();
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
void closeEvent(QCloseEvent *e) override;
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
|
||||||
void leaveEventHook(QEvent *e) override;
|
|
||||||
void leaveToChildEvent(QEvent *e, QWidget *child) override;
|
|
||||||
bool eventHook(QEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class Content;
|
||||||
class Button;
|
class Button;
|
||||||
using State = Call::State;
|
using State = Call::State;
|
||||||
using Type = Call::Type;
|
using Type = Call::Type;
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
|
||||||
|
|
||||||
// AbstractTooltipShower interface
|
// AbstractTooltipShower interface
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
bool tooltipWindowActive() const override;
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
|
void paint(QRect clip);
|
||||||
|
|
||||||
|
void initWindow();
|
||||||
|
void initWidget();
|
||||||
void initControls();
|
void initControls();
|
||||||
void reinitWithCall(Call *call);
|
void reinitWithCall(Call *call);
|
||||||
void initLayout();
|
void initLayout();
|
||||||
void initGeometry();
|
void initGeometry();
|
||||||
void hideDeactivated();
|
|
||||||
void createBottomImage();
|
void handleClose();
|
||||||
void createDefaultCacheImage();
|
void handleMouseMove(not_null<QMouseEvent*> e);
|
||||||
|
|
||||||
QRect signalBarsRect() const;
|
QRect signalBarsRect() const;
|
||||||
void paintSignalBarsBg(Painter &p);
|
void paintSignalBarsBg(Painter &p);
|
||||||
|
|
||||||
|
void updateFingerprintGeometry();
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
void updateHangupGeometry();
|
void updateHangupGeometry();
|
||||||
void updateStatusGeometry();
|
void updateStatusGeometry();
|
||||||
|
@ -90,26 +87,16 @@ private:
|
||||||
void updateStatusText(State state);
|
void updateStatusText(State state);
|
||||||
void startDurationUpdateTimer(crl::time currentDuration);
|
void startDurationUpdateTimer(crl::time currentDuration);
|
||||||
void fillFingerprint();
|
void fillFingerprint();
|
||||||
void toggleOpacityAnimation(bool visible);
|
|
||||||
void finishAnimating();
|
|
||||||
void destroyDelayed();
|
|
||||||
void setIncomingShown(bool shown);
|
void setIncomingShown(bool shown);
|
||||||
|
|
||||||
[[nodiscard]] bool hasActiveVideo() const;
|
|
||||||
void checkForInactiveHide();
|
|
||||||
void checkForInactiveShow();
|
|
||||||
void refreshOutgoingPreviewInBody(State state);
|
void refreshOutgoingPreviewInBody(State state);
|
||||||
|
|
||||||
Call *_call = nullptr;
|
Call *_call = nullptr;
|
||||||
not_null<UserData*> _user;
|
not_null<UserData*> _user;
|
||||||
|
|
||||||
bool _useTransparency = true;
|
const std::unique_ptr<Ui::Window> _window;
|
||||||
bool _incomingShown = false;
|
|
||||||
style::margins _padding;
|
|
||||||
|
|
||||||
bool _dragging = false;
|
bool _incomingShown = false;
|
||||||
QPoint _dragStartMousePosition;
|
|
||||||
QPoint _dragStartMyPosition;
|
|
||||||
|
|
||||||
rpl::lifetime _callLifetime;
|
rpl::lifetime _callLifetime;
|
||||||
|
|
||||||
|
@ -136,13 +123,6 @@ private:
|
||||||
base::Timer _updateDurationTimer;
|
base::Timer _updateDurationTimer;
|
||||||
base::Timer _updateOuterRippleTimer;
|
base::Timer _updateOuterRippleTimer;
|
||||||
|
|
||||||
bool _visible = false;
|
|
||||||
|
|
||||||
Ui::Animations::Simple _opacityAnimation;
|
|
||||||
QPixmap _animationCache;
|
|
||||||
QPixmap _bottomCache;
|
|
||||||
QPixmap _cache;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Calls
|
} // namespace Calls
|
||||||
|
|
|
@ -80,6 +80,10 @@ void VideoBubble::updateGeometry(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect VideoBubble::geometry() const {
|
||||||
|
return _content.isHidden() ? QRect() : _content.geometry();
|
||||||
|
}
|
||||||
|
|
||||||
void VideoBubble::applyBoundingRect(QRect rect) {
|
void VideoBubble::applyBoundingRect(QRect rect) {
|
||||||
_boundingRect = rect;
|
_boundingRect = rect;
|
||||||
_geometryDirty = true;
|
_geometryDirty = true;
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
QRect boundingRect,
|
QRect boundingRect,
|
||||||
QSize sizeMin = QSize(),
|
QSize sizeMin = QSize(),
|
||||||
QSize sizeMax = QSize());
|
QSize sizeMax = QSize());
|
||||||
|
[[nodiscard]] QRect geometry() const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
return _content.lifetime();
|
return _content.lifetime();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f7bcb15bad3879b448a9b5bd3f9827009151b2f3
|
Subproject commit 608b25bd32d01e233df0d78ccb5fd97028a82ae9
|
Loading…
Add table
Reference in a new issue