mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 07:37:11 +02:00
Hide controls in wide video mode.
This commit is contained in:
parent
0db0abe608
commit
64c34b7029
6 changed files with 192 additions and 36 deletions
|
@ -30,7 +30,9 @@ LargeVideo::LargeVideo(
|
|||
, _st(st)
|
||||
, _pin(st::groupCallLargeVideoPin)
|
||||
, _pinButton(&_content)
|
||||
, _topControls(_st.controlsAlign == style::al_top) {
|
||||
, _controlsShown(_st.controlsAlign == style::al_top)
|
||||
, _topControls(_st.controlsAlign == style::al_top)
|
||||
, _controlsShownRatio(_controlsShown.current() ? 1. : 0.) {
|
||||
_content.setVisible(visible);
|
||||
setup(std::move(track), std::move(pinned));
|
||||
}
|
||||
|
@ -47,10 +49,25 @@ void LargeVideo::setGeometry(int x, int y, int width, int height) {
|
|||
_content.setGeometry(x, y, width, height);
|
||||
}
|
||||
|
||||
void LargeVideo::setControlsShown(bool shown) {
|
||||
if (_mouseInside == shown) {
|
||||
return;
|
||||
}
|
||||
_mouseInside = shown;
|
||||
if (!_toggleControlsScheduled) {
|
||||
_toggleControlsScheduled = true;
|
||||
crl::on_main(&_content, [=] { toggleControls(); });
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<bool> LargeVideo::pinToggled() const {
|
||||
return _pinButton.clicks() | rpl::map([=] { return !_pinned; });
|
||||
}
|
||||
|
||||
rpl::producer<float64> LargeVideo::controlsShown() const {
|
||||
return _controlsShownRatio.value();
|
||||
}
|
||||
|
||||
rpl::producer<QSize> LargeVideo::trackSizeValue() const {
|
||||
return _trackSize.value();
|
||||
}
|
||||
|
@ -60,10 +77,26 @@ void LargeVideo::setup(
|
|||
rpl::producer<bool> pinned) {
|
||||
_content.setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
_content.events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::Enter) {
|
||||
Ui::Integration::Instance().registerLeaveSubscription(&_content);
|
||||
setControlsShown(true);
|
||||
} else if (e->type() == QEvent::Leave) {
|
||||
Ui::Integration::Instance().unregisterLeaveSubscription(
|
||||
&_content);
|
||||
setControlsShown(false);
|
||||
}
|
||||
}, _content.lifetime());
|
||||
|
||||
rpl::combine(
|
||||
_content.shownValue(),
|
||||
std::move(track)
|
||||
) | rpl::map([=](bool shown, LargeVideoTrack track) {
|
||||
if (!shown) {
|
||||
_controlsAnimation.stop();
|
||||
_controlsShownRatio = _controlsShown.current() ? 1. : 0.;
|
||||
}
|
||||
return shown ? track : LargeVideoTrack();
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](LargeVideoTrack track) {
|
||||
|
@ -90,6 +123,34 @@ void LargeVideo::setup(
|
|||
setupControls(std::move(pinned));
|
||||
}
|
||||
|
||||
void LargeVideo::toggleControls() {
|
||||
_toggleControlsScheduled = false;
|
||||
const auto shown = _mouseInside;
|
||||
if (_controlsShown.current() == shown) {
|
||||
return;
|
||||
}
|
||||
_controlsShown = shown;
|
||||
const auto callback = [=] {
|
||||
_controlsShownRatio = _controlsAnimation.value(
|
||||
_controlsShown.current() ? 1. : 0.);
|
||||
if (_topControls) {
|
||||
_content.update(0, 0, _content.width(), _st.shadowHeight);
|
||||
} else {
|
||||
_content.update();
|
||||
}
|
||||
updateControlsGeometry();
|
||||
};
|
||||
if (_content.isHidden()) {
|
||||
updateControlsGeometry();
|
||||
} else {
|
||||
_controlsAnimation.start(
|
||||
callback,
|
||||
shown ? 0. : 1.,
|
||||
shown ? 1. : 0.,
|
||||
140);
|
||||
}
|
||||
}
|
||||
|
||||
void LargeVideo::setupControls(rpl::producer<bool> pinned) {
|
||||
std::move(pinned) | rpl::start_with_next([=](bool pinned) {
|
||||
_pinned = pinned;
|
||||
|
@ -186,13 +247,17 @@ void LargeVideo::paint(QRect clip) {
|
|||
}
|
||||
|
||||
void LargeVideo::paintControls(Painter &p, QRect clip) {
|
||||
const auto shown = _controlsAnimation.value(_controlsShown ? 1. : 0.);
|
||||
if (shown == 0.) {
|
||||
const auto shown = _controlsShownRatio.current();
|
||||
if (shown == 0. && _topControls) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto width = _content.width();
|
||||
const auto height = _content.height();
|
||||
const auto fullShift = _st.statusPosition.y() + st::normalFont->height;
|
||||
const auto shift = _topControls
|
||||
? anim::interpolate(-fullShift, 0, shown)
|
||||
: 0;
|
||||
|
||||
// Shadow.
|
||||
if (_shadow.isNull()) {
|
||||
|
@ -204,7 +269,9 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
}
|
||||
const auto shadowRect = QRect(
|
||||
0,
|
||||
_topControls ? 0 : (height - _st.shadowHeight),
|
||||
(_topControls
|
||||
? anim::interpolate(-_st.shadowHeight, 0, shown)
|
||||
: (height - _st.shadowHeight)),
|
||||
width,
|
||||
_st.shadowHeight);
|
||||
const auto shadowFill = shadowRect.intersected(clip);
|
||||
|
@ -231,7 +298,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
- _st.namePosition.x();
|
||||
const auto nameLeft = _st.namePosition.x();
|
||||
const auto nameTop = _topControls
|
||||
? _st.namePosition.y()
|
||||
? (_st.namePosition.y() + shift)
|
||||
: (height - _st.namePosition.y());
|
||||
_track.row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width);
|
||||
|
||||
|
@ -239,7 +306,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
p.setPen(st::groupCallVideoSubTextFg);
|
||||
const auto statusLeft = _st.statusPosition.x();
|
||||
const auto statusTop = _topControls
|
||||
? _st.statusPosition.y()
|
||||
? (_st.statusPosition.y() + shift)
|
||||
: (height - _st.statusPosition.y());
|
||||
_track.row->paintComplexStatusText(
|
||||
p,
|
||||
|
@ -255,7 +322,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
const auto &icon = st::groupCallLargeVideoCrossLine.icon;
|
||||
const auto iconLeft = width - _st.iconPosition.x() - icon.width();
|
||||
const auto iconTop = _topControls
|
||||
? _st.iconPosition.y()
|
||||
? (_st.iconPosition.y() + shift)
|
||||
: (height - _st.iconPosition.y() - icon.height());
|
||||
_track.row->paintMuteIcon(
|
||||
p,
|
||||
|
@ -268,7 +335,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
? (width - _st.pinPosition.x() - pin.width())
|
||||
: _st.pinPosition.x();
|
||||
const auto pinTop = _topControls
|
||||
? _st.pinPosition.y()
|
||||
? (_st.pinPosition.y() + shift)
|
||||
: (height - _st.pinPosition.y() - pin.height());
|
||||
_pin.paint(p, pinLeft, pinTop, _pinned ? 1. : 0.);
|
||||
}
|
||||
|
|
|
@ -61,8 +61,10 @@ public:
|
|||
void raise();
|
||||
void setVisible(bool visible);
|
||||
void setGeometry(int x, int y, int width, int height);
|
||||
void setControlsShown(bool shown);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> pinToggled() const;
|
||||
[[nodiscard]] rpl::producer<float64> controlsShown() const;
|
||||
[[nodiscard]] rpl::producer<QSize> trackSizeValue() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
|
@ -99,6 +101,7 @@ private:
|
|||
void paint(QRect clip);
|
||||
void paintControls(Painter &p, QRect clip);
|
||||
void updateControlsGeometry();
|
||||
void toggleControls();
|
||||
|
||||
Content _content;
|
||||
const style::GroupCallLargeVideo &_st;
|
||||
|
@ -107,9 +110,12 @@ private:
|
|||
Ui::CrossLineAnimation _pin;
|
||||
Ui::AbstractButton _pinButton;
|
||||
Ui::Animations::Simple _controlsAnimation;
|
||||
bool _topControls = false;
|
||||
rpl::variable<bool> _controlsShown = true;
|
||||
const bool _topControls = true;
|
||||
bool _pinned = false;
|
||||
bool _controlsShown = true;
|
||||
bool _mouseInside = false;
|
||||
bool _toggleControlsScheduled = false;
|
||||
rpl::variable<float64> _controlsShownRatio = 1.;
|
||||
rpl::variable<QSize> _trackSize;
|
||||
rpl::lifetime _trackLifetime;
|
||||
|
||||
|
|
|
@ -1016,6 +1016,21 @@ void Panel::setupPinnedVideo() {
|
|||
_call->pinVideoEndpoint(large);
|
||||
}
|
||||
}, _pinnedVideo->lifetime());
|
||||
_pinnedVideo->controlsShown(
|
||||
) | rpl::filter([=](float64 shown) {
|
||||
return (_pinnedVideoControlsShown != shown);
|
||||
}) | rpl::start_with_next([=](float64 shown) {
|
||||
const auto hiding = (shown <= _pinnedVideoControlsShown);
|
||||
_pinnedVideoControlsShown = shown;
|
||||
if (_mode == PanelMode::Wide) {
|
||||
if (hiding && _trackControlsLifetime) {
|
||||
_trackControlsLifetime.destroy();
|
||||
} else if (!hiding && !_trackControlsLifetime) {
|
||||
trackControls();
|
||||
}
|
||||
updateButtonsGeometry();
|
||||
}
|
||||
}, _pinnedVideo->lifetime());
|
||||
|
||||
raiseControls();
|
||||
}
|
||||
|
@ -1536,6 +1551,7 @@ bool Panel::updateMode() {
|
|||
|
||||
void Panel::refreshControlsBackground() {
|
||||
if (_mode != PanelMode::Wide) {
|
||||
_trackControlsLifetime.destroy();
|
||||
_controlsBackground.destroy();
|
||||
} else if (_controlsBackground) {
|
||||
return;
|
||||
|
@ -1556,17 +1572,92 @@ void Panel::refreshControlsBackground() {
|
|||
auto p = QPainter(_controlsBackground.data());
|
||||
corners->paint(p, _controlsBackground->rect());
|
||||
}, lifetime);
|
||||
|
||||
if (_pinnedVideoControlsShown > 0.) {
|
||||
trackControls();
|
||||
}
|
||||
raiseControls();
|
||||
}
|
||||
|
||||
void Panel::trackControls() {
|
||||
const auto trackOne = [&](auto &&widget) {
|
||||
if (widget) {
|
||||
widget->events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::Enter) {
|
||||
_pinnedVideo->setControlsShown(true);
|
||||
} else if (e->type() == QEvent::Leave) {
|
||||
_pinnedVideo->setControlsShown(false);
|
||||
}
|
||||
}, _trackControlsLifetime);
|
||||
}
|
||||
};
|
||||
trackOne(_mute);
|
||||
trackOne(_video);
|
||||
trackOne(_screenShare);
|
||||
trackOne(_settings);
|
||||
trackOne(_callShare);
|
||||
trackOne(_hangup);
|
||||
trackOne(_controlsBackground);
|
||||
}
|
||||
|
||||
void Panel::updateControlsGeometry() {
|
||||
if (widget()->size().isEmpty() || (!_settings && !_callShare)) {
|
||||
return;
|
||||
}
|
||||
updateButtonsGeometry();
|
||||
updateMembersGeometry();
|
||||
refreshTitle();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
const auto controlsOnTheLeft = true;
|
||||
#else // Q_OS_MAC
|
||||
const auto controlsOnTheLeft = _controls->geometry().center().x()
|
||||
< widget()->width() / 2;
|
||||
#endif // Q_OS_MAC
|
||||
const auto menux = st::groupCallMenuTogglePosition.x();
|
||||
const auto menuy = st::groupCallMenuTogglePosition.y();
|
||||
if (controlsOnTheLeft) {
|
||||
if (_menuToggle) {
|
||||
_menuToggle->moveToRight(menux, menuy);
|
||||
} else if (_joinAsToggle) {
|
||||
_joinAsToggle->moveToRight(menux, menuy);
|
||||
}
|
||||
} else {
|
||||
if (_menuToggle) {
|
||||
_menuToggle->moveToLeft(menux, menuy);
|
||||
} else if (_joinAsToggle) {
|
||||
_joinAsToggle->moveToLeft(menux, menuy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::updateButtonsGeometry() {
|
||||
const auto toggle = [&](bool shown) {
|
||||
const auto toggleOne = [&](auto &widget) {
|
||||
if (widget && widget->isHidden() == shown) {
|
||||
widget->setVisible(shown);
|
||||
}
|
||||
};
|
||||
toggleOne(_mute);
|
||||
toggleOne(_video);
|
||||
toggleOne(_screenShare);
|
||||
toggleOne(_settings);
|
||||
toggleOne(_callShare);
|
||||
toggleOne(_hangup);
|
||||
};
|
||||
if (_videoMode.current()) {
|
||||
_mute->setStyle(st::callMuteButtonSmall);
|
||||
toggle(_mode != PanelMode::Wide || _pinnedVideoControlsShown > 0.);
|
||||
|
||||
const auto buttonsTop = widget()->height()
|
||||
- st::groupCallButtonBottomSkipSmall;
|
||||
- st::groupCallButtonBottomSkipSmall
|
||||
+ (_mode == PanelMode::Wide
|
||||
? anim::interpolate(
|
||||
st::groupCallButtonBottomSkipSmall,
|
||||
0,
|
||||
_pinnedVideoControlsShown)
|
||||
: 0);
|
||||
const auto addSkip = st::callMuteButtonSmall.active.outerRadius;
|
||||
const auto muteSize = _mute->innerSize().width() + 2 * addSkip;
|
||||
const auto skip = (_video ? 1 : 2) * st::groupCallButtonSkipSmall;
|
||||
|
@ -1619,6 +1710,8 @@ void Panel::updateControlsGeometry() {
|
|||
}
|
||||
} else {
|
||||
_mute->setStyle(st::callMuteButton);
|
||||
toggle(true);
|
||||
|
||||
const auto muteTop = widget()->height()
|
||||
- st::groupCallMuteBottomSkip;
|
||||
const auto buttonsTop = widget()->height()
|
||||
|
@ -1640,30 +1733,6 @@ void Panel::updateControlsGeometry() {
|
|||
_hangup->setStyle(st::groupCallHangup);
|
||||
_hangup->moveToRight(leftButtonLeft, buttonsTop);
|
||||
}
|
||||
updateMembersGeometry();
|
||||
refreshTitle();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
const auto controlsOnTheLeft = true;
|
||||
#else // Q_OS_MAC
|
||||
const auto controlsOnTheLeft = _controls->geometry().center().x()
|
||||
< widget()->width() / 2;
|
||||
#endif // Q_OS_MAC
|
||||
const auto menux = st::groupCallMenuTogglePosition.x();
|
||||
const auto menuy = st::groupCallMenuTogglePosition.y();
|
||||
if (controlsOnTheLeft) {
|
||||
if (_menuToggle) {
|
||||
_menuToggle->moveToRight(menux, menuy);
|
||||
} else if (_joinAsToggle) {
|
||||
_joinAsToggle->moveToRight(menux, menuy);
|
||||
}
|
||||
} else {
|
||||
if (_menuToggle) {
|
||||
_menuToggle->moveToLeft(menux, menuy);
|
||||
} else if (_joinAsToggle) {
|
||||
_joinAsToggle->moveToLeft(menux, menuy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::updateMembersGeometry() {
|
||||
|
|
|
@ -91,10 +91,12 @@ private:
|
|||
|
||||
bool handleClose();
|
||||
void startScheduledNow();
|
||||
void trackControls();
|
||||
void raiseControls();
|
||||
|
||||
bool updateMode();
|
||||
void updateControlsGeometry();
|
||||
void updateButtonsGeometry();
|
||||
void updateMembersGeometry();
|
||||
void refreshControlsBackground();
|
||||
void showControls();
|
||||
|
@ -143,7 +145,8 @@ private:
|
|||
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
|
||||
object_ptr<Members> _members = { nullptr };
|
||||
std::unique_ptr<LargeVideo> _pinnedVideo;
|
||||
rpl::lifetime _pinnedTrackLifetime;
|
||||
float64 _pinnedVideoControlsShown = 1.;
|
||||
rpl::lifetime _trackControlsLifetime;
|
||||
object_ptr<Ui::FlatLabel> _startsIn = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _countdown = { nullptr };
|
||||
std::shared_ptr<Ui::GroupCallScheduledLeft> _countdownData;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "styles/style_calls.h"
|
||||
|
||||
#include <QtCore/QtMath>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
@ -1038,6 +1039,10 @@ rpl::producer<Qt::MouseButton> CallMuteButton::clicks() {
|
|||
});
|
||||
}
|
||||
|
||||
rpl::producer<not_null<QEvent*>> CallMuteButton::events() const {
|
||||
return _content->events();
|
||||
}
|
||||
|
||||
QSize CallMuteButton::innerSize() const {
|
||||
return innerGeometry().size();
|
||||
}
|
||||
|
@ -1071,6 +1076,10 @@ void CallMuteButton::setVisible(bool visible) {
|
|||
_blobs->setVisible(visible);
|
||||
}
|
||||
|
||||
bool CallMuteButton::isHidden() const {
|
||||
return _content->isHidden();
|
||||
}
|
||||
|
||||
void CallMuteButton::raise() {
|
||||
_blobs->raise();
|
||||
_content->raise();
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
void setStyle(const style::CallMuteButton &st);
|
||||
void setLevel(float level);
|
||||
[[nodiscard]] rpl::producer<Qt::MouseButton> clicks();
|
||||
[[nodiscard]] rpl::producer<not_null<QEvent*>> events() const;
|
||||
|
||||
[[nodiscard]] QSize innerSize() const;
|
||||
[[nodiscard]] QRect innerGeometry() const;
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
void hide() {
|
||||
setVisible(false);
|
||||
}
|
||||
[[nodiscard]] bool isHidden() const;
|
||||
void raise();
|
||||
void lower();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue