mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 07:37:11 +02:00
Nice three-button narrow mode with gradient fading.
This commit is contained in:
parent
c12a50544e
commit
385b98ff3d
7 changed files with 310 additions and 92 deletions
|
@ -195,8 +195,8 @@ callMuteButtonLabel: FlatLabel(defaultFlatLabel) {
|
|||
}
|
||||
}
|
||||
callMuteButtonActiveInner: IconButton {
|
||||
width: 136px;
|
||||
height: 165px;
|
||||
width: 112px;
|
||||
height: 138px;
|
||||
}
|
||||
callMuteButtonSmallActiveInner: IconButton {
|
||||
width: 68px;
|
||||
|
@ -205,7 +205,7 @@ callMuteButtonSmallActiveInner: IconButton {
|
|||
callMuteButtonActive: CallButton {
|
||||
button: callMuteButtonActiveInner;
|
||||
bg: groupCallLive1;
|
||||
bgSize: 100px;
|
||||
bgSize: 77px;
|
||||
bgPosition: point(18px, 18px);
|
||||
outerRadius: 18px;
|
||||
outerBg: callAnswerBgOuter;
|
||||
|
@ -221,10 +221,10 @@ callMuteButton: CallMuteButton {
|
|||
sublabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: groupCallMemberNotJoinedStatus;
|
||||
}
|
||||
labelsSkip: 5px;
|
||||
sublabelSkip: 19px;
|
||||
lottieSize: size(67px, 67px);
|
||||
lottieTop: 35px;
|
||||
labelsSkip: 8px;
|
||||
sublabelSkip: 14px;
|
||||
lottieSize: size(54px, 54px);
|
||||
lottieTop: 31px;
|
||||
}
|
||||
callMuteButtonSmallActive: CallButton(callMuteButtonActive) {
|
||||
button: callMuteButtonSmallActiveInner;
|
||||
|
@ -685,7 +685,6 @@ groupCallTitleTop: 8px;
|
|||
groupCallSubtitleTop: 26px;
|
||||
groupCallWideVideoTop: 24px;
|
||||
|
||||
groupCallMembersMargin: margins(16px, 16px, 16px, 28px);
|
||||
groupCallAddMember: SettingsButton(defaultSettingsButton) {
|
||||
textFg: groupCallMemberNotJoinedStatus;
|
||||
textFgOver: groupCallMemberNotJoinedStatus;
|
||||
|
@ -780,6 +779,10 @@ groupCallSettingsInner: IconButton(callButton) {
|
|||
groupCallShareInner: IconButton(groupCallSettingsInner) {
|
||||
icon: icon {{ "calls/group_calls_share", groupCallIconFg }};
|
||||
}
|
||||
groupCallVideoInner: IconButton(groupCallSettingsInner) {
|
||||
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
|
||||
iconPosition: point(-1px, 16px);
|
||||
}
|
||||
groupCallHangupInner: IconButton(callButton) {
|
||||
icon: icon {{ "calls/call_discard", groupCallIconFg }};
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
|
@ -792,6 +795,15 @@ groupCallSettings: CallButton(callMicrophoneMute) {
|
|||
groupCallShare: CallButton(groupCallSettings) {
|
||||
button: groupCallShareInner;
|
||||
}
|
||||
groupCallVideo: CallButton(groupCallSettings) {
|
||||
button: groupCallVideoInner;
|
||||
}
|
||||
groupCallVideoInnerActive: IconButton(groupCallVideoInner) {
|
||||
icon: icon {{ "calls/call_camera_active", groupCallIconFg }};
|
||||
}
|
||||
groupCallVideoActive: CallButton(groupCallVideo) {
|
||||
button: groupCallVideoInnerActive;
|
||||
}
|
||||
groupCallHangup: CallButton(callHangup) {
|
||||
button: groupCallHangupInner;
|
||||
bg: groupCallLeaveBg;
|
||||
|
@ -813,17 +825,14 @@ groupCallHangupSmall: CallButton(groupCallHangup) {
|
|||
height: 76px;
|
||||
}
|
||||
}
|
||||
groupCallVideoSmallInner: IconButton(groupCallSettingsInner) {
|
||||
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
|
||||
iconPosition: point(-1px, 16px);
|
||||
height: 76px;
|
||||
}
|
||||
groupCallVideoSmall: CallButton(groupCallShareSmall) {
|
||||
button: groupCallVideoSmallInner;
|
||||
button: IconButton(groupCallVideoInner) {
|
||||
height: 76px;
|
||||
}
|
||||
}
|
||||
groupCallVideoActiveSmall: CallButton(groupCallVideoSmall) {
|
||||
button: IconButton(groupCallVideoSmallInner) {
|
||||
icon: icon {{ "calls/call_camera_active", groupCallIconFg }};
|
||||
button: IconButton(groupCallVideoInnerActive) {
|
||||
height: 76px;
|
||||
}
|
||||
}
|
||||
groupCallScreenShareSmall: CallButton(groupCallShareSmall) {
|
||||
|
@ -832,15 +841,20 @@ groupCallScreenShareSmall: CallButton(groupCallShareSmall) {
|
|||
height: 76px;
|
||||
}
|
||||
}
|
||||
groupCallButtonSkip: 43px;
|
||||
groupCallButtonSkip: 40px;
|
||||
groupCallButtonSkipSmall: 4px;
|
||||
groupCallButtonBottomSkip: 145px;
|
||||
groupCallButtonBottomSkip: 113px;
|
||||
groupCallButtonBottomSkipSmall: 95px;
|
||||
groupCallButtonBottomSkipWide: 122px;
|
||||
groupCallMembersBottomSkipSmall: 72px;
|
||||
groupCallControlsBackMargin: margins(2px, 2px, 2px, 2px);
|
||||
groupCallControlsBackRadius: 12px;
|
||||
groupCallMuteBottomSkip: 160px;
|
||||
groupCallMuteBottomSkip: 116px;
|
||||
|
||||
groupCallMembersMargin: margins(16px, 16px, 16px, 60px);
|
||||
groupCallMembersBottomSkip: 80px;
|
||||
groupCallMembersShadowHeight: 160px;
|
||||
groupCallMembersFadeSkip: 10px;
|
||||
groupCallMembersFadeHeight: 100px;
|
||||
|
||||
groupCallTopBarUserpics: GroupCallUserpics {
|
||||
size: 28px;
|
||||
|
|
|
@ -438,16 +438,27 @@ void LargeVideo::paintControls(Painter &p, QRect clip) {
|
|||
_track.row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width);
|
||||
}
|
||||
|
||||
QImage GenerateShadow(int height, int topAlpha, int bottomAlpha) {
|
||||
QImage GenerateShadow(
|
||||
int height,
|
||||
int topAlpha,
|
||||
int bottomAlpha,
|
||||
QColor color) {
|
||||
Expects(topAlpha >= 0 && topAlpha < 256);
|
||||
Expects(bottomAlpha >= 0 && bottomAlpha < 256);
|
||||
Expects(height * style::DevicePixelRatio() < 65536);
|
||||
|
||||
const auto base = (uint32(color.red()) << 16)
|
||||
| (uint32(color.green()) << 8)
|
||||
| uint32(color.blue());
|
||||
const auto premultiplied = (topAlpha == bottomAlpha) || !base;
|
||||
auto result = QImage(
|
||||
QSize(1, height * style::DevicePixelRatio()),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
(premultiplied
|
||||
? QImage::Format_ARGB32_Premultiplied
|
||||
: QImage::Format_ARGB32));
|
||||
if (topAlpha == bottomAlpha) {
|
||||
result.fill(QColor(0, 0, 0, topAlpha));
|
||||
color.setAlpha(topAlpha);
|
||||
result.fill(color);
|
||||
return result;
|
||||
}
|
||||
constexpr auto kShift = 16;
|
||||
|
@ -460,13 +471,17 @@ QImage GenerateShadow(int height, int topAlpha, int bottomAlpha) {
|
|||
auto ints = reinterpret_cast<uint32*>(result.bits());
|
||||
if (topAlpha < bottomAlpha) {
|
||||
for (auto i = uint32(0); i != till; i += step) {
|
||||
*ints++ = ((topAlpha + (i >> kShift)) << 24);
|
||||
*ints++ = base | ((topAlpha + (i >> kShift)) << 24);
|
||||
}
|
||||
} else {
|
||||
for (auto i = uint32(0); i != till; i += step) {
|
||||
*ints++ = ((topAlpha - (i >> kShift)) << 24);
|
||||
*ints++ = base | ((topAlpha - (i >> kShift)) << 24);
|
||||
}
|
||||
}
|
||||
if (!premultiplied) {
|
||||
result = std::move(result).convertToFormat(
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ private:
|
|||
[[nodiscard]] QImage GenerateShadow(
|
||||
int height,
|
||||
int topAlpha,
|
||||
int bottomAlpha);
|
||||
int bottomAlpha,
|
||||
QColor color = QColor(0, 0, 0));
|
||||
|
||||
} // namespace Calls::Group
|
||||
|
|
|
@ -1677,9 +1677,6 @@ auto Members::kickParticipantRequests() const
|
|||
}
|
||||
|
||||
int Members::desiredHeight() const {
|
||||
const auto addMember = _addMemberButton.current();
|
||||
const auto top = _pinnedVideoWrap->height()
|
||||
+ (addMember ? addMember->height() : 0);
|
||||
const auto count = [&] {
|
||||
if (const auto real = _call->lookupReal()) {
|
||||
return real->fullCount();
|
||||
|
@ -1690,16 +1687,18 @@ int Members::desiredHeight() const {
|
|||
const auto single = /*(_mode.current() == PanelMode::Wide)
|
||||
? (st::groupCallNarrowSize.height() + st::groupCallNarrowRowSkip * 2)
|
||||
: */st::groupCallMembersList.item.height;
|
||||
return top
|
||||
const auto desired = (_layout->height() - _list->height())
|
||||
+ (use * single)
|
||||
+ (use ? st::lineWidth : 0);
|
||||
return std::max(height(), desired);
|
||||
}
|
||||
|
||||
rpl::producer<int> Members::desiredHeightValue() const {
|
||||
return rpl::combine(
|
||||
heightValue(),
|
||||
_addMemberButton.value(),
|
||||
_listController->fullCountValue()
|
||||
_listController->fullCountValue(),
|
||||
_mode.value()
|
||||
) | rpl::map([=] {
|
||||
return desiredHeight();
|
||||
});
|
||||
|
@ -1810,6 +1809,16 @@ void Members::setMode(PanelMode mode) {
|
|||
// : PeerListContent::Mode::Default);
|
||||
}
|
||||
|
||||
QRect Members::getInnerGeometry() const {
|
||||
const auto addMembers = _addMemberButton.current();
|
||||
const auto add = addMembers ? addMembers->height() : 0;
|
||||
return QRect(
|
||||
0,
|
||||
-_scroll->scrollTop(),
|
||||
width(),
|
||||
_list->y() + _list->height());
|
||||
}
|
||||
|
||||
rpl::producer<int> Members::fullCountValue() const {
|
||||
return _listController->fullCountValue();
|
||||
}
|
||||
|
@ -1817,10 +1826,19 @@ rpl::producer<int> Members::fullCountValue() const {
|
|||
void Members::setupList() {
|
||||
_listController->setStyleOverrides(&st::groupCallMembersList);
|
||||
_list = _layout->add(object_ptr<ListWidget>(
|
||||
this,
|
||||
_layout.get(),
|
||||
_listController.get()));
|
||||
const auto skip = _layout->add(object_ptr<Ui::RpWidget>(_layout.get()));
|
||||
_mode.value(
|
||||
) | rpl::start_with_next([=](PanelMode mode) {
|
||||
skip->resize(skip->width(), (mode == PanelMode::Default)
|
||||
? st::groupCallMembersBottomSkip
|
||||
: 0);
|
||||
}, skip->lifetime());
|
||||
|
||||
_layout->heightValue(
|
||||
rpl::combine(
|
||||
_mode.value(),
|
||||
_layout->heightValue()
|
||||
) | rpl::start_with_next([=] {
|
||||
resizeToList();
|
||||
}, _layout->lifetime());
|
||||
|
@ -2030,7 +2048,7 @@ void Members::setupFakeRoundCorners() {
|
|||
};
|
||||
|
||||
const auto create = [&](QPoint imagePartOrigin) {
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(this);
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(_layout.get());
|
||||
result->show();
|
||||
result->resize(size, size);
|
||||
result->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
@ -2050,14 +2068,24 @@ void Members::setupFakeRoundCorners() {
|
|||
const auto bottomleft = create({ 0, shift });
|
||||
const auto bottomright = create({ shift, shift });
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](QSize size) {
|
||||
topleft->move(0, 0);
|
||||
topright->move(size.width() - topright->width(), 0);
|
||||
bottomleft->move(0, size.height() - bottomleft->height());
|
||||
bottomright->move(
|
||||
size.width() - bottomright->width(),
|
||||
size.height() - bottomright->height());
|
||||
rpl::combine(
|
||||
_list->geometryValue(),
|
||||
_addMemberButton.value() | rpl::map([=](Ui::RpWidget *widget) {
|
||||
topleft->raise();
|
||||
topright->raise();
|
||||
bottomleft->raise();
|
||||
bottomright->raise();
|
||||
return widget ? widget->heightValue() : rpl::single(0);
|
||||
}) | rpl::flatten_latest()
|
||||
) | rpl::start_with_next([=](QRect list, int addMembers) {
|
||||
const auto left = list.x();
|
||||
const auto top = list.y() - addMembers;
|
||||
const auto right = list.x() + list.width() - topright->width();
|
||||
const auto bottom = list.y() + list.height() - bottomleft->height();
|
||||
topleft->move(left, top);
|
||||
topright->move(right, top);
|
||||
bottomleft->move(left, bottom);
|
||||
bottomright->move(right, bottom);
|
||||
}, lifetime());
|
||||
|
||||
refreshImage();
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
[[nodiscard]] MembersRow *lookupRow(not_null<PeerData*> peer) const;
|
||||
|
||||
void setMode(PanelMode mode);
|
||||
[[nodiscard]] QRect getInnerGeometry() const;
|
||||
|
||||
private:
|
||||
class Controller;
|
||||
|
|
|
@ -384,6 +384,16 @@ struct Panel::VideoTile {
|
|||
VideoEndpoint endpoint;
|
||||
};
|
||||
|
||||
struct Panel::ControlsBackgroundNarrow {
|
||||
explicit ControlsBackgroundNarrow(not_null<QWidget*> parent)
|
||||
: shadow(parent)
|
||||
, blocker(parent) {
|
||||
}
|
||||
|
||||
Ui::RpWidget shadow;
|
||||
Ui::RpWidget blocker;
|
||||
};
|
||||
|
||||
Panel::Panel(not_null<GroupCall*> call)
|
||||
: _call(call)
|
||||
, _peer(call->peer())
|
||||
|
@ -697,6 +707,8 @@ void Panel::initControls() {
|
|||
) | rpl::start_with_next([=](not_null<Data::GroupCall*> real) {
|
||||
setupRealMuteButtonState(real);
|
||||
}, _callLifetime);
|
||||
|
||||
refreshControlsBackground();
|
||||
}
|
||||
|
||||
void Panel::refreshLeftButton() {
|
||||
|
@ -799,7 +811,7 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
|
|||
real->scheduleDateValue(),
|
||||
real->scheduleStartSubscribedValue(),
|
||||
Data::CanManageGroupCallValue(_peer),
|
||||
_videoMode.value()
|
||||
_mode.value()
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::filter(
|
||||
_2 != GroupCall::InstanceState::TransitionToRtc
|
||||
|
@ -809,7 +821,8 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
|
|||
TimeId scheduleDate,
|
||||
bool scheduleStartSubscribed,
|
||||
bool canManage,
|
||||
bool videoMode) {
|
||||
PanelMode mode) {
|
||||
const auto wide = (mode == PanelMode::Wide);
|
||||
using Type = Ui::CallMuteButtonType;
|
||||
_mute->setState(Ui::CallMuteButtonState{
|
||||
.text = (scheduleDate
|
||||
|
@ -821,19 +834,19 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
|
|||
: state == GroupCall::InstanceState::Disconnected
|
||||
? tr::lng_group_call_connecting(tr::now)
|
||||
: mute == MuteState::ForceMuted
|
||||
? (videoMode
|
||||
? (wide
|
||||
? tr::lng_group_call_force_muted_small(tr::now)
|
||||
: tr::lng_group_call_force_muted(tr::now))
|
||||
: mute == MuteState::RaisedHand
|
||||
? (videoMode
|
||||
? (wide
|
||||
? tr::lng_group_call_raised_hand_small(tr::now)
|
||||
: tr::lng_group_call_raised_hand(tr::now))
|
||||
: mute == MuteState::Muted
|
||||
? tr::lng_group_call_unmute(tr::now)
|
||||
: (videoMode
|
||||
: (wide
|
||||
? tr::lng_group_call_you_are_live_small(tr::now)
|
||||
: tr::lng_group_call_you_are_live(tr::now))),
|
||||
.subtext = ((scheduleDate || videoMode)
|
||||
.subtext = ((scheduleDate || wide)
|
||||
? QString()
|
||||
: state == GroupCall::InstanceState::Disconnected
|
||||
? QString()
|
||||
|
@ -930,6 +943,10 @@ void Panel::setupScheduledLabels(rpl::producer<TimeId> date) {
|
|||
}, _startsWhen->lifetime());
|
||||
}
|
||||
|
||||
PanelMode Panel::mode() const {
|
||||
return _mode.current();
|
||||
}
|
||||
|
||||
void Panel::setupMembers() {
|
||||
if (_members) {
|
||||
return;
|
||||
|
@ -942,7 +959,7 @@ void Panel::setupMembers() {
|
|||
_members.create(widget(), _call);
|
||||
setupPinnedVideo();
|
||||
|
||||
_members->setMode(_mode);
|
||||
_members->setMode(mode());
|
||||
_members->show();
|
||||
|
||||
_members->desiredHeightValue(
|
||||
|
@ -985,7 +1002,7 @@ void Panel::setupMembers() {
|
|||
|
||||
_call->videoEndpointPinnedValue(
|
||||
) | rpl::start_with_next([=](const VideoEndpoint &pinned) {
|
||||
if (_mode == PanelMode::Wide) {
|
||||
if (mode() == PanelMode::Wide) {
|
||||
refreshTilesGeometry();
|
||||
} else if (pinned) {
|
||||
enlargeVideo();
|
||||
|
@ -1062,8 +1079,12 @@ void Panel::minimizeVideo() {
|
|||
}
|
||||
|
||||
void Panel::raiseControls() {
|
||||
if (_controlsBackground) {
|
||||
_controlsBackground->raise();
|
||||
if (_controlsBackgroundWide) {
|
||||
_controlsBackgroundWide->raise();
|
||||
}
|
||||
if (_controlsBackgroundNarrow) {
|
||||
_controlsBackgroundNarrow->shadow.raise();
|
||||
_controlsBackgroundNarrow->blocker.raise();
|
||||
}
|
||||
const auto buttons = {
|
||||
&_settings,
|
||||
|
@ -1084,7 +1105,7 @@ void Panel::refreshTilesGeometry() {
|
|||
const auto outer = _pinnedVideoWrap->size();
|
||||
if (_videoTiles.empty()
|
||||
|| outer.isEmpty()
|
||||
|| _mode == PanelMode::Default) {
|
||||
|| mode() == PanelMode::Default) {
|
||||
return;
|
||||
}
|
||||
struct Geometry {
|
||||
|
@ -1204,7 +1225,7 @@ void Panel::setupPinnedVideo() {
|
|||
auto video = std::make_unique<LargeVideo>(
|
||||
raw,
|
||||
st::groupCallLargeVideoWide,
|
||||
(_mode == PanelMode::Wide),
|
||||
(mode() == PanelMode::Wide),
|
||||
rpl::single(LargeVideoTrack{ track.track.get(), row }),
|
||||
_call->videoEndpointPinnedValue() | rpl::map(_1 == endpoint));
|
||||
|
||||
|
@ -1781,7 +1802,7 @@ bool Panel::updateMode() {
|
|||
const auto wide = _call->videoCall()
|
||||
&& (widget()->width() >= st::groupCallWideModeWidthMin);
|
||||
const auto mode = wide ? PanelMode::Wide : PanelMode::Default;
|
||||
if (_mode == mode) {
|
||||
if (_mode.current() == mode) {
|
||||
return false;
|
||||
}
|
||||
_mode = mode;
|
||||
|
@ -1813,15 +1834,120 @@ bool Panel::updateMode() {
|
|||
}
|
||||
|
||||
void Panel::refreshControlsBackground() {
|
||||
if (_mode != PanelMode::Wide) {
|
||||
if (mode() == PanelMode::Default) {
|
||||
trackControls(false);
|
||||
_controlsBackground.destroy();
|
||||
} else if (_controlsBackground) {
|
||||
return;
|
||||
_controlsBackgroundWide.destroy();
|
||||
if (_controlsBackgroundNarrow) {
|
||||
return;
|
||||
}
|
||||
setupControlsBackgroundNarrow();
|
||||
} else {
|
||||
_controlsBackgroundNarrow = nullptr;
|
||||
if (_controlsBackgroundWide) {
|
||||
return;
|
||||
}
|
||||
setupControlsBackgroundWide();
|
||||
}
|
||||
_controlsBackground.create(widget());
|
||||
_controlsBackground->show();
|
||||
auto &lifetime = _controlsBackground->lifetime();
|
||||
raiseControls();
|
||||
updateButtonsGeometry();
|
||||
}
|
||||
|
||||
void Panel::setupControlsBackgroundNarrow() {
|
||||
_controlsBackgroundNarrow = std::make_unique<ControlsBackgroundNarrow>(
|
||||
widget());
|
||||
_controlsBackgroundNarrow->shadow.show();
|
||||
_controlsBackgroundNarrow->blocker.show();
|
||||
auto &lifetime = _controlsBackgroundNarrow->shadow.lifetime();
|
||||
|
||||
const auto factor = cIntRetinaFactor();
|
||||
const auto height = std::max(
|
||||
st::groupCallMembersShadowHeight,
|
||||
st::groupCallMembersFadeSkip + st::groupCallMembersFadeHeight);
|
||||
const auto full = lifetime.make_state<QImage>(
|
||||
QSize(1, height * factor),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
rpl::single(
|
||||
rpl::empty_value()
|
||||
) | rpl::then(
|
||||
style::PaletteChanged()
|
||||
) | rpl::start_with_next([=] {
|
||||
full->fill(Qt::transparent);
|
||||
|
||||
auto p = QPainter(full);
|
||||
const auto bottom = (height - st::groupCallMembersFadeSkip) * factor;
|
||||
p.fillRect(
|
||||
0,
|
||||
bottom,
|
||||
full->width(),
|
||||
st::groupCallMembersFadeSkip * factor,
|
||||
st::groupCallMembersBg);
|
||||
p.drawImage(
|
||||
QRect(
|
||||
0,
|
||||
bottom - (st::groupCallMembersFadeHeight * factor),
|
||||
full->width(),
|
||||
st::groupCallMembersFadeHeight * factor),
|
||||
GenerateShadow(
|
||||
st::groupCallMembersFadeHeight,
|
||||
0,
|
||||
255,
|
||||
st::groupCallMembersBg->c));
|
||||
p.drawImage(
|
||||
QRect(
|
||||
0,
|
||||
(height - st::groupCallMembersShadowHeight) * factor,
|
||||
full->width(),
|
||||
st::groupCallMembersShadowHeight * factor),
|
||||
GenerateShadow(
|
||||
st::groupCallMembersShadowHeight,
|
||||
0,
|
||||
255,
|
||||
st::groupCallBg->c));
|
||||
}, lifetime);
|
||||
|
||||
_controlsBackgroundNarrow->shadow.resize(
|
||||
(widget()->width()
|
||||
- st::groupCallMembersMargin.left()
|
||||
- st::groupCallMembersMargin.right()),
|
||||
height);
|
||||
_controlsBackgroundNarrow->shadow.paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
auto p = QPainter(&_controlsBackgroundNarrow->shadow);
|
||||
clip = clip.intersected(_controlsBackgroundNarrow->shadow.rect());
|
||||
const auto inner = _members->getInnerGeometry().translated(
|
||||
_members->x() - _controlsBackgroundNarrow->shadow.x(),
|
||||
_members->y() - _controlsBackgroundNarrow->shadow.y());
|
||||
const auto faded = clip.intersected(inner);
|
||||
if (!faded.isEmpty()) {
|
||||
const auto factor = cIntRetinaFactor();
|
||||
p.drawImage(
|
||||
faded,
|
||||
*full,
|
||||
QRect(
|
||||
0,
|
||||
faded.y() * factor,
|
||||
full->width(),
|
||||
faded.height() * factor));
|
||||
}
|
||||
const auto bottom = inner.y() + inner.height();
|
||||
const auto after = clip.intersected(QRect(
|
||||
0,
|
||||
bottom,
|
||||
inner.width(),
|
||||
_controlsBackgroundNarrow->shadow.height() - bottom));
|
||||
if (!after.isEmpty()) {
|
||||
p.fillRect(after, st::groupCallBg);
|
||||
}
|
||||
}, lifetime);
|
||||
_controlsBackgroundNarrow->shadow.setAttribute(
|
||||
Qt::WA_TransparentForMouseEvents);
|
||||
_controlsBackgroundNarrow->blocker.setUpdatesEnabled(false);
|
||||
}
|
||||
|
||||
void Panel::setupControlsBackgroundWide() {
|
||||
_controlsBackgroundWide.create(widget());
|
||||
_controlsBackgroundWide->show();
|
||||
auto &lifetime = _controlsBackgroundWide->lifetime();
|
||||
const auto color = lifetime.make_state<style::complex_color>([] {
|
||||
auto result = st::groupCallBg->c;
|
||||
result.setAlphaF(kControlsBackgroundOpacity);
|
||||
|
@ -1830,14 +1956,13 @@ void Panel::refreshControlsBackground() {
|
|||
const auto corners = lifetime.make_state<Ui::RoundRect>(
|
||||
st::groupCallControlsBackRadius,
|
||||
color->color());
|
||||
_controlsBackground->paintRequest(
|
||||
_controlsBackgroundWide->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto p = QPainter(_controlsBackground.data());
|
||||
corners->paint(p, _controlsBackground->rect());
|
||||
auto p = QPainter(_controlsBackgroundWide.data());
|
||||
corners->paint(p, _controlsBackgroundWide->rect());
|
||||
}, lifetime);
|
||||
|
||||
trackControls(true);
|
||||
raiseControls();
|
||||
}
|
||||
|
||||
void Panel::trackControls(bool track) {
|
||||
|
@ -1875,7 +2000,7 @@ void Panel::trackControls(bool track) {
|
|||
trackOne(_settings);
|
||||
trackOne(_callShare);
|
||||
trackOne(_hangup);
|
||||
trackOne(_controlsBackground);
|
||||
trackOne(_controlsBackgroundWide);
|
||||
}
|
||||
|
||||
void Panel::updateControlsGeometry() {
|
||||
|
@ -1923,23 +2048,20 @@ void Panel::updateButtonsGeometry() {
|
|||
toggleOne(_callShare);
|
||||
toggleOne(_hangup);
|
||||
};
|
||||
if (_videoMode.current()) {
|
||||
if (mode() == PanelMode::Wide) {
|
||||
_mute->setStyle(st::callMuteButtonSmall);
|
||||
const auto shown = _wideControlsAnimation.value(
|
||||
_wideControlsShown ? 1. : 0.);
|
||||
toggle(_mode != PanelMode::Wide || shown > 0.);
|
||||
toggle(shown > 0.);
|
||||
|
||||
for (const auto &tile : _videoTiles) {
|
||||
tile.video->setControlsShown(shown);
|
||||
}
|
||||
|
||||
const auto buttonsTop = widget()->height()
|
||||
- (_mode == PanelMode::Wide
|
||||
? anim::interpolate(
|
||||
0,
|
||||
st::groupCallButtonBottomSkipWide,
|
||||
shown)
|
||||
: st::groupCallButtonBottomSkipSmall);
|
||||
const auto buttonsTop = widget()->height() - anim::interpolate(
|
||||
0,
|
||||
st::groupCallButtonBottomSkipWide,
|
||||
shown);
|
||||
const auto addSkip = st::callMuteButtonSmall.active.outerRadius;
|
||||
const auto muteSize = _mute->innerSize().width() + 2 * addSkip;
|
||||
const auto skip = (_video ? 1 : 2) * st::groupCallButtonSkipSmall;
|
||||
|
@ -1951,28 +2073,32 @@ void Panel::updateButtonsGeometry() {
|
|||
const auto membersSkip = st::groupCallNarrowSkip;
|
||||
const auto membersWidth = st::groupCallNarrowMembersWidth
|
||||
+ 2 * membersSkip;
|
||||
auto left = (_mode == PanelMode::Default)
|
||||
? (widget()->width() - fullWidth) / 2
|
||||
: ((widget()->width()
|
||||
- membersWidth
|
||||
- membersSkip
|
||||
- fullWidth) / 2);
|
||||
auto left = (widget()->width()
|
||||
- membersWidth
|
||||
- membersSkip
|
||||
- fullWidth) / 2;
|
||||
_mute->moveInner({ left + addSkip, buttonsTop + addSkip });
|
||||
left += muteSize + skip;
|
||||
if (_video) {
|
||||
_video->setStyle(
|
||||
st::groupCallVideoSmall,
|
||||
&st::groupCallVideoActiveSmall);
|
||||
_video->moveToLeft(left, buttonsTop);
|
||||
left += _video->width() + skip;
|
||||
}
|
||||
if (_screenShare) {
|
||||
_screenShare->setVisible(true);
|
||||
_screenShare->moveToLeft(left, buttonsTop);
|
||||
left += _video->width() + skip;
|
||||
}
|
||||
if (_settings) {
|
||||
_settings->setVisible(true);
|
||||
_settings->setStyle(st::groupCallSettingsSmall);
|
||||
_settings->moveToLeft(left, buttonsTop);
|
||||
left += _settings->width() + skip;
|
||||
}
|
||||
if (_callShare) {
|
||||
_callShare->setVisible(true);
|
||||
_callShare->setStyle(st::groupCallShareSmall);
|
||||
_callShare->moveToLeft(left, buttonsTop);
|
||||
left += _callShare->width() + skip;
|
||||
|
@ -1980,13 +2106,13 @@ void Panel::updateButtonsGeometry() {
|
|||
_hangup->setStyle(st::groupCallHangupSmall);
|
||||
_hangup->moveToLeft(left, buttonsTop);
|
||||
left += _hangup->width();
|
||||
if (_controlsBackground) {
|
||||
if (_controlsBackgroundWide) {
|
||||
const auto rect = QRect(
|
||||
left - fullWidth,
|
||||
buttonsTop,
|
||||
fullWidth,
|
||||
_hangup->height());
|
||||
_controlsBackground->setGeometry(
|
||||
_controlsBackgroundWide->setGeometry(
|
||||
rect.marginsAdded(st::groupCallControlsBackMargin));
|
||||
}
|
||||
} else {
|
||||
|
@ -2003,17 +2129,46 @@ void Panel::updateButtonsGeometry() {
|
|||
+ 2 * st::groupCallButtonSkip;
|
||||
_mute->moveInner({ (widget()->width() - muteSize) / 2, muteTop });
|
||||
const auto leftButtonLeft = (widget()->width() - fullWidth) / 2;
|
||||
if (_screenShare) {
|
||||
_screenShare->setVisible(false);
|
||||
}
|
||||
if (_video) {
|
||||
_video->setStyle(st::groupCallVideo, &st::groupCallVideoActive);
|
||||
_video->moveToLeft(leftButtonLeft, buttonsTop);
|
||||
}
|
||||
if (_settings) {
|
||||
_settings->setVisible(!_video);
|
||||
_settings->setStyle(st::groupCallSettings);
|
||||
_settings->moveToLeft(leftButtonLeft, buttonsTop);
|
||||
}
|
||||
if (_callShare) {
|
||||
_callShare->setVisible(!_video);
|
||||
_callShare->setStyle(st::groupCallShare);
|
||||
_callShare->moveToLeft(leftButtonLeft, buttonsTop);
|
||||
}
|
||||
_hangup->setStyle(st::groupCallHangup);
|
||||
_hangup->moveToRight(leftButtonLeft, buttonsTop);
|
||||
}
|
||||
if (_controlsBackgroundNarrow) {
|
||||
const auto left = st::groupCallMembersMargin.left();
|
||||
const auto width = (widget()->width()
|
||||
- st::groupCallMembersMargin.left()
|
||||
- st::groupCallMembersMargin.right());
|
||||
_controlsBackgroundNarrow->shadow.setGeometry(
|
||||
left,
|
||||
(widget()->height()
|
||||
- st::groupCallMembersMargin.bottom()
|
||||
- _controlsBackgroundNarrow->shadow.height()),
|
||||
width,
|
||||
_controlsBackgroundNarrow->shadow.height());
|
||||
_controlsBackgroundNarrow->blocker.setGeometry(
|
||||
left,
|
||||
(widget()->height()
|
||||
- st::groupCallMembersMargin.bottom()
|
||||
- st::groupCallMembersBottomSkip),
|
||||
width,
|
||||
st::groupCallMembersBottomSkip);
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::updateMembersGeometry() {
|
||||
|
@ -2021,7 +2176,7 @@ void Panel::updateMembersGeometry() {
|
|||
return;
|
||||
}
|
||||
const auto desiredHeight = _members->desiredHeight();
|
||||
if (_mode == PanelMode::Wide) {
|
||||
if (mode() == PanelMode::Wide) {
|
||||
const auto skip = st::groupCallNarrowSkip;
|
||||
const auto membersWidth = st::groupCallNarrowMembersWidth;
|
||||
const auto top = st::groupCallWideVideoTop;
|
||||
|
@ -2036,9 +2191,7 @@ void Panel::updateMembersGeometry() {
|
|||
widget()->width() - membersWidth - 3 * skip,
|
||||
widget()->height() - top - skip);
|
||||
} else {
|
||||
const auto membersBottom = _videoMode.current()
|
||||
? (widget()->height() - st::groupCallMembersBottomSkipSmall)
|
||||
: (widget()->height() - st::groupCallMuteBottomSkip);
|
||||
const auto membersBottom = widget()->height();
|
||||
const auto membersTop = st::groupCallMembersTop;
|
||||
const auto availableHeight = membersBottom
|
||||
- st::groupCallMembersMargin.bottom()
|
||||
|
@ -2086,7 +2239,7 @@ void Panel::refreshTitle() {
|
|||
_title->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
}
|
||||
refreshTitleGeometry();
|
||||
if (!_subtitle && _mode == PanelMode::Default) {
|
||||
if (!_subtitle && mode() == PanelMode::Default) {
|
||||
_subtitle.create(
|
||||
widget(),
|
||||
rpl::single(
|
||||
|
@ -2141,7 +2294,7 @@ void Panel::refreshTitleGeometry() {
|
|||
: fullRect;
|
||||
const auto best = _title->naturalWidth();
|
||||
const auto from = (widget()->width() - best) / 2;
|
||||
const auto top = (_mode == PanelMode::Default)
|
||||
const auto top = (mode() == PanelMode::Default)
|
||||
? st::groupCallTitleTop
|
||||
: (st::groupCallWideVideoTop
|
||||
- st::groupCallTitleLabel.style.font->height) / 2;
|
||||
|
|
|
@ -71,9 +71,12 @@ public:
|
|||
private:
|
||||
using State = GroupCall::State;
|
||||
struct VideoTile;
|
||||
struct ControlsBackgroundNarrow;
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
|
||||
|
||||
[[nodiscard]] PanelMode mode() const;
|
||||
|
||||
void paint(QRect clip);
|
||||
|
||||
void initWindow();
|
||||
|
@ -102,6 +105,8 @@ private:
|
|||
void updateButtonsGeometry();
|
||||
void updateMembersGeometry();
|
||||
void refreshControlsBackground();
|
||||
void setupControlsBackgroundWide();
|
||||
void setupControlsBackgroundNarrow();
|
||||
void showControls();
|
||||
void refreshLeftButton();
|
||||
void refreshTilesGeometry();
|
||||
|
@ -134,7 +139,7 @@ private:
|
|||
|
||||
const std::unique_ptr<Ui::Window> _window;
|
||||
const std::unique_ptr<Ui::LayerManager> _layerBg;
|
||||
PanelMode _mode = PanelMode();
|
||||
rpl::variable<PanelMode> _mode;
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
std::unique_ptr<Ui::Platform::TitleControls> _controls;
|
||||
|
@ -167,7 +172,8 @@ private:
|
|||
bool _wideControlsShown = false;
|
||||
Ui::Animations::Simple _wideControlsAnimation;
|
||||
|
||||
object_ptr<Ui::RpWidget> _controlsBackground = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _controlsBackgroundWide = { nullptr };
|
||||
std::unique_ptr<ControlsBackgroundNarrow> _controlsBackgroundNarrow;
|
||||
object_ptr<Ui::CallButton> _settings = { nullptr };
|
||||
object_ptr<Ui::CallButton> _callShare = { nullptr };
|
||||
object_ptr<Ui::CallButton> _video = { nullptr };
|
||||
|
|
Loading…
Add table
Reference in a new issue