Improve narrow participants column design.
This commit is contained in:
parent
0dcc7a05f7
commit
00ce302b38
|
@ -2069,8 +2069,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_group_call_context_remove_hand" = "Cancel request to speak";
|
"lng_group_call_context_remove_hand" = "Cancel request to speak";
|
||||||
"lng_group_call_context_mute_for_me" = "Mute for me";
|
"lng_group_call_context_mute_for_me" = "Mute for me";
|
||||||
"lng_group_call_context_unmute_for_me" = "Unmute for me";
|
"lng_group_call_context_unmute_for_me" = "Unmute for me";
|
||||||
"lng_group_call_context_pin_video" = "Pin video";
|
"lng_group_call_context_pin_camera" = "Pin video";
|
||||||
"lng_group_call_context_unpin_video" = "Unpin video";
|
"lng_group_call_context_unpin_camera" = "Unpin video";
|
||||||
|
"lng_group_call_context_pin_screen" = "Pin screencast";
|
||||||
|
"lng_group_call_context_unpin_screen" = "Unpin screencast";
|
||||||
"lng_group_call_context_remove" = "Remove";
|
"lng_group_call_context_remove" = "Remove";
|
||||||
"lng_group_call_remove_channel" = "Remove {channel} from the voice chat?";
|
"lng_group_call_remove_channel" = "Remove {channel} from the voice chat?";
|
||||||
"lng_group_call_duration_days#one" = "{count} day";
|
"lng_group_call_duration_days#one" = "{count} day";
|
||||||
|
|
|
@ -811,9 +811,6 @@ groupCallHangupSmall: CallButton(groupCallHangup) {
|
||||||
groupCallVideoSmallInner: IconButton(groupCallSettingsInner) {
|
groupCallVideoSmallInner: IconButton(groupCallSettingsInner) {
|
||||||
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
|
icon: icon {{ "calls/call_camera_muted", groupCallIconFg }};
|
||||||
iconPosition: point(-1px, 16px);
|
iconPosition: point(-1px, 16px);
|
||||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
|
||||||
color: groupCallLeaveBgRipple;
|
|
||||||
}
|
|
||||||
height: 76px;
|
height: 76px;
|
||||||
}
|
}
|
||||||
groupCallVideoSmall: CallButton(groupCallShareSmall) {
|
groupCallVideoSmall: CallButton(groupCallShareSmall) {
|
||||||
|
@ -1136,6 +1133,19 @@ desktopCaptureSubmit: RoundButton(desktopCaptureCancel) {
|
||||||
|
|
||||||
groupCallNarrowSkip: 9px;
|
groupCallNarrowSkip: 9px;
|
||||||
groupCallNarrowRowSkip: 8px;
|
groupCallNarrowRowSkip: 8px;
|
||||||
groupCallNarrowSize: size(90px, 90px);
|
groupCallNarrowSize: size(144px, 90px);
|
||||||
groupCallWideModeWidthMin: 520px;
|
groupCallWideModeWidthMin: 520px;
|
||||||
groupCallWideModeSize: size(720px, 480px);
|
groupCallWideModeSize: size(720px, 480px);
|
||||||
|
groupCallNarrowAddMemberHeight: 32px;
|
||||||
|
|
||||||
|
groupCallNarrowAddMember: RoundButton(defaultActiveButton) {
|
||||||
|
textFg: groupCallMemberNotJoinedStatus;
|
||||||
|
textFgOver: groupCallMemberNotJoinedStatus;
|
||||||
|
textBg: groupCallMembersBg;
|
||||||
|
textBgOver: groupCallMembersBgOver;
|
||||||
|
|
||||||
|
height: 32px;
|
||||||
|
radius: roundRadiusLarge;
|
||||||
|
|
||||||
|
ripple: groupCallRipple;
|
||||||
|
}
|
||||||
|
|
|
@ -388,6 +388,10 @@ GroupCall::GroupCall(
|
||||||
, _joinHash(info.joinHash)
|
, _joinHash(info.joinHash)
|
||||||
, _id(inputCall.c_inputGroupCall().vid().v)
|
, _id(inputCall.c_inputGroupCall().vid().v)
|
||||||
, _scheduleDate(info.scheduleDate)
|
, _scheduleDate(info.scheduleDate)
|
||||||
|
, _cameraOutgoing(std::make_unique<Webrtc::VideoTrack>(
|
||||||
|
Webrtc::VideoState::Inactive))
|
||||||
|
, _screenOutgoing(std::make_unique<Webrtc::VideoTrack>(
|
||||||
|
Webrtc::VideoState::Inactive))
|
||||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||||
, _checkJoinedTimer([=] { checkJoined(); })
|
, _checkJoinedTimer([=] { checkJoined(); })
|
||||||
, _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
|
, _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
|
||||||
|
@ -460,8 +464,15 @@ GroupCall::~GroupCall() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GroupCall::isSharingScreen() const {
|
bool GroupCall::isSharingScreen() const {
|
||||||
return _screenOutgoing
|
return (_screenOutgoing->state() == Webrtc::VideoState::Active);
|
||||||
&& (_screenOutgoing->state() == Webrtc::VideoState::Active);
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> GroupCall::isSharingScreenValue() const {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
return _screenOutgoing->stateValue(
|
||||||
|
) | rpl::map(
|
||||||
|
_1 == Webrtc::VideoState::Active
|
||||||
|
) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &GroupCall::screenSharingEndpoint() const {
|
const std::string &GroupCall::screenSharingEndpoint() const {
|
||||||
|
@ -469,8 +480,15 @@ const std::string &GroupCall::screenSharingEndpoint() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GroupCall::isSharingCamera() const {
|
bool GroupCall::isSharingCamera() const {
|
||||||
return _cameraOutgoing
|
return (_cameraOutgoing->state() == Webrtc::VideoState::Active);
|
||||||
&& (_cameraOutgoing->state() == Webrtc::VideoState::Active);
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> GroupCall::isSharingCameraValue() const {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
return _cameraOutgoing->stateValue(
|
||||||
|
) | rpl::map(
|
||||||
|
_1 == Webrtc::VideoState::Active
|
||||||
|
) | rpl::distinct_until_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &GroupCall::cameraSharingEndpoint() const {
|
const std::string &GroupCall::cameraSharingEndpoint() const {
|
||||||
|
@ -611,7 +629,7 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
|
||||||
const auto wasSounding = data.was && data.was->sounding;
|
const auto wasSounding = data.was && data.was->sounding;
|
||||||
if (nowSpeaking == wasSpeaking && nowSounding == wasSounding) {
|
if (nowSpeaking == wasSpeaking && nowSounding == wasSounding) {
|
||||||
return;
|
return;
|
||||||
} else if (!_videoEndpointPinned.empty()) {
|
} else if (!_videoEndpointPinned.current().empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nowScreenEndpoint != newLarge
|
if (nowScreenEndpoint != newLarge
|
||||||
|
@ -876,7 +894,7 @@ void GroupCall::setMyEndpointType(
|
||||||
}
|
}
|
||||||
const auto nowLarge = activeVideoEndpointType(
|
const auto nowLarge = activeVideoEndpointType(
|
||||||
_videoEndpointLarge.current());
|
_videoEndpointLarge.current());
|
||||||
if (_videoEndpointPinned.empty()
|
if (_videoEndpointPinned.current().empty()
|
||||||
&& ((type == EndpointType::Screen
|
&& ((type == EndpointType::Screen
|
||||||
&& nowLarge != EndpointType::Screen)
|
&& nowLarge != EndpointType::Screen)
|
||||||
|| (type == EndpointType::Camera
|
|| (type == EndpointType::Camera
|
||||||
|
@ -1604,14 +1622,10 @@ void GroupCall::setupMediaDevices() {
|
||||||
void GroupCall::ensureOutgoingVideo() {
|
void GroupCall::ensureOutgoingVideo() {
|
||||||
Expects(_id != 0);
|
Expects(_id != 0);
|
||||||
|
|
||||||
if (_cameraOutgoing) {
|
if (_videoInited) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_videoInited = true;
|
||||||
_cameraOutgoing = std::make_unique<Webrtc::VideoTrack>(
|
|
||||||
Webrtc::VideoState::Inactive);
|
|
||||||
_screenOutgoing = std::make_unique<Webrtc::VideoTrack>(
|
|
||||||
Webrtc::VideoState::Inactive);
|
|
||||||
|
|
||||||
//static const auto hasDevices = [] {
|
//static const auto hasDevices = [] {
|
||||||
// return !Webrtc::GetVideoInputList().empty();
|
// return !Webrtc::GetVideoInputList().empty();
|
||||||
|
@ -2057,7 +2071,7 @@ void GroupCall::setIncomingVideoEndpoints(
|
||||||
feedOne(cameraSharingEndpoint());
|
feedOne(cameraSharingEndpoint());
|
||||||
feedOne(screenSharingEndpoint());
|
feedOne(screenSharingEndpoint());
|
||||||
if (!newLarge.empty() && !newLargeFound) {
|
if (!newLarge.empty() && !newLargeFound) {
|
||||||
newLarge = _videoEndpointPinned = std::string();
|
_videoEndpointPinned = newLarge = std::string();
|
||||||
}
|
}
|
||||||
if (newLarge.empty()) {
|
if (newLarge.empty()) {
|
||||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||||
|
@ -2105,7 +2119,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
||||||
feedOne(cameraSharingEndpoint(), EndpointType::Camera);
|
feedOne(cameraSharingEndpoint(), EndpointType::Camera);
|
||||||
feedOne(screenSharingEndpoint(), EndpointType::Screen);
|
feedOne(screenSharingEndpoint(), EndpointType::Screen);
|
||||||
if (!newLarge.empty() && !newLargeFound) {
|
if (!newLarge.empty() && !newLargeFound) {
|
||||||
newLarge = _videoEndpointPinned = std::string();
|
_videoEndpointPinned = newLarge = std::string();
|
||||||
}
|
}
|
||||||
if (newLarge.empty()) {
|
if (newLarge.empty()) {
|
||||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||||
|
@ -2453,8 +2467,7 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) {
|
||||||
MTP_bool(muted() != MuteState::Active),
|
MTP_bool(muted() != MuteState::Active),
|
||||||
MTP_int(100000), // volume
|
MTP_int(100000), // volume
|
||||||
MTP_bool(muted() == MuteState::RaisedHand),
|
MTP_bool(muted() == MuteState::RaisedHand),
|
||||||
MTP_bool(!_cameraOutgoing
|
MTP_bool(_cameraOutgoing->state() != Webrtc::VideoState::Active)
|
||||||
|| _cameraOutgoing->state() != Webrtc::VideoState::Active)
|
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](const MTPUpdates &result) {
|
||||||
_updateMuteRequestId = 0;
|
_updateMuteRequestId = 0;
|
||||||
_peer->session().api().applyUpdates(result);
|
_peer->session().api().applyUpdates(result);
|
||||||
|
@ -2472,7 +2485,9 @@ void GroupCall::pinVideoEndpoint(const std::string &endpoint) {
|
||||||
if (endpoint.empty()) {
|
if (endpoint.empty()) {
|
||||||
_videoEndpointPinned = endpoint;
|
_videoEndpointPinned = endpoint;
|
||||||
} else if (streamsVideo(endpoint)) {
|
} else if (streamsVideo(endpoint)) {
|
||||||
_videoEndpointLarge = _videoEndpointPinned = endpoint;
|
_videoEndpointPinned = std::string();
|
||||||
|
_videoEndpointLarge = endpoint;
|
||||||
|
_videoEndpointPinned = endpoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,10 +235,13 @@ public:
|
||||||
&& activeVideoEndpointType(endpoint) != EndpointType::None;
|
&& activeVideoEndpointType(endpoint) != EndpointType::None;
|
||||||
}
|
}
|
||||||
[[nodiscard]] const std::string &videoEndpointPinned() const {
|
[[nodiscard]] const std::string &videoEndpointPinned() const {
|
||||||
return _videoEndpointPinned;
|
return _videoEndpointPinned.current();
|
||||||
|
}
|
||||||
|
[[nodiscard]] rpl::producer<std::string> videoEndpointPinnedValue() const {
|
||||||
|
return _videoEndpointPinned.value();
|
||||||
}
|
}
|
||||||
void pinVideoEndpoint(const std::string &endpoint);
|
void pinVideoEndpoint(const std::string &endpoint);
|
||||||
[[nodiscard]] std::string videoEndpointLarge() const {
|
[[nodiscard]] const std::string &videoEndpointLarge() const {
|
||||||
return _videoEndpointLarge.current();
|
return _videoEndpointLarge.current();
|
||||||
}
|
}
|
||||||
[[nodiscard]] auto videoEndpointLargeValue() const
|
[[nodiscard]] auto videoEndpointLargeValue() const
|
||||||
|
@ -266,8 +269,10 @@ public:
|
||||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||||
void setCurrentVideoDevice(const QString &deviceId);
|
void setCurrentVideoDevice(const QString &deviceId);
|
||||||
[[nodiscard]] bool isSharingScreen() const;
|
[[nodiscard]] bool isSharingScreen() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> isSharingScreenValue() const;
|
||||||
[[nodiscard]] const std::string &screenSharingEndpoint() const;
|
[[nodiscard]] const std::string &screenSharingEndpoint() const;
|
||||||
[[nodiscard]] bool isSharingCamera() const;
|
[[nodiscard]] bool isSharingCamera() const;
|
||||||
|
[[nodiscard]] rpl::producer<bool> isSharingCameraValue() const;
|
||||||
[[nodiscard]] const std::string &cameraSharingEndpoint() const;
|
[[nodiscard]] const std::string &cameraSharingEndpoint() const;
|
||||||
[[nodiscard]] QString screenSharingDeviceId() const;
|
[[nodiscard]] QString screenSharingDeviceId() const;
|
||||||
void toggleVideo(bool active);
|
void toggleVideo(bool active);
|
||||||
|
@ -462,12 +467,14 @@ private:
|
||||||
std::unique_ptr<Webrtc::VideoTrack> _screenOutgoing;
|
std::unique_ptr<Webrtc::VideoTrack> _screenOutgoing;
|
||||||
QString _screenDeviceId;
|
QString _screenDeviceId;
|
||||||
|
|
||||||
|
bool _videoInited = false;
|
||||||
|
|
||||||
rpl::event_stream<LevelUpdate> _levelUpdates;
|
rpl::event_stream<LevelUpdate> _levelUpdates;
|
||||||
rpl::event_stream<StreamsVideoUpdate> _streamsVideoUpdated;
|
rpl::event_stream<StreamsVideoUpdate> _streamsVideoUpdated;
|
||||||
base::flat_set<std::string> _incomingVideoEndpoints;
|
base::flat_set<std::string> _incomingVideoEndpoints;
|
||||||
base::flat_map<std::string, EndpointType> _activeVideoEndpoints;
|
base::flat_map<std::string, EndpointType> _activeVideoEndpoints;
|
||||||
rpl::variable<std::string> _videoEndpointLarge;
|
rpl::variable<std::string> _videoEndpointLarge;
|
||||||
std::string _videoEndpointPinned;
|
rpl::variable<std::string> _videoEndpointPinned;
|
||||||
std::unique_ptr<LargeTrack> _videoLargeTrackWrap;
|
std::unique_ptr<LargeTrack> _videoLargeTrackWrap;
|
||||||
rpl::variable<Webrtc::VideoTrack*> _videoLargeTrack;
|
rpl::variable<Webrtc::VideoTrack*> _videoLargeTrack;
|
||||||
base::flat_map<uint32, Data::LastSpokeTimes> _lastSpoke;
|
base::flat_map<uint32, Data::LastSpokeTimes> _lastSpoke;
|
||||||
|
|
|
@ -185,7 +185,8 @@ public:
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
int size,
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
PanelMode mode,
|
PanelMode mode,
|
||||||
bool selected = false);
|
bool selected = false);
|
||||||
|
|
||||||
|
@ -256,19 +257,32 @@ private:
|
||||||
void ensureUserpicCache(
|
void ensureUserpicCache(
|
||||||
std::shared_ptr<Data::CloudImageView> &view,
|
std::shared_ptr<Data::CloudImageView> &view,
|
||||||
int size);
|
int size);
|
||||||
bool paintVideo(Painter &p, int x, int y, int size, PanelMode mode);
|
bool paintVideo(
|
||||||
|
Painter &p,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
|
PanelMode mode);
|
||||||
[[nodiscard]] static std::tuple<int, int, int> UserpicInWideMode(
|
[[nodiscard]] static std::tuple<int, int, int> UserpicInWideMode(
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int size);
|
int sizew,
|
||||||
void paintBlobs(Painter &p, int x, int y, int size, PanelMode mode);
|
int sizeh);
|
||||||
|
void paintBlobs(
|
||||||
|
Painter &p,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int sizew,
|
||||||
|
int sizeh, PanelMode mode);
|
||||||
void paintScaledUserpic(
|
void paintScaledUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
int size,
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
PanelMode mode);
|
PanelMode mode);
|
||||||
|
|
||||||
const not_null<RowDelegate*> _delegate;
|
const not_null<RowDelegate*> _delegate;
|
||||||
|
@ -694,7 +708,13 @@ void Row::ensureUserpicCache(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
bool Row::paintVideo(
|
||||||
|
Painter &p,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
|
PanelMode mode) {
|
||||||
if (!_videoTrackShown) {
|
if (!_videoTrackShown) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -706,12 +726,14 @@ bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
||||||
|| _videoTrackShown->state() != Webrtc::VideoState::Active) {
|
|| _videoTrackShown->state() != Webrtc::VideoState::Active) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto resize = (videoSize.width() > videoSize.height())
|
const auto videow = videoSize.width();
|
||||||
? QSize(videoSize.width() * size / videoSize.height(), size)
|
const auto videoh = videoSize.height();
|
||||||
: QSize(size, videoSize.height() * size / videoSize.width());
|
const auto resize = (videow * sizeh > videoh * sizew)
|
||||||
|
? QSize(videow * sizeh / videoh, sizeh)
|
||||||
|
: QSize(sizew, videoh * sizew / videow);
|
||||||
const auto request = Webrtc::FrameRequest{
|
const auto request = Webrtc::FrameRequest{
|
||||||
.resize = resize * cIntRetinaFactor(),
|
.resize = resize * cIntRetinaFactor(),
|
||||||
.outer = QSize(size, size) * cIntRetinaFactor(),
|
.outer = QSize(sizew, sizeh) * cIntRetinaFactor(),
|
||||||
};
|
};
|
||||||
const auto frame = _videoTrackShown->frame(request);
|
const auto frame = _videoTrackShown->frame(request);
|
||||||
auto copy = frame; // #TODO calls optimize.
|
auto copy = frame; // #TODO calls optimize.
|
||||||
|
@ -727,18 +749,30 @@ bool Row::paintVideo(Painter &p, int x, int y, int size, PanelMode mode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<int, int, int> Row::UserpicInWideMode(int x, int y, int size) {
|
std::tuple<int, int, int> Row::UserpicInWideMode(
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int sizew,
|
||||||
|
int sizeh) {
|
||||||
const auto useSize = st::groupCallMembersList.item.photoSize;
|
const auto useSize = st::groupCallMembersList.item.photoSize;
|
||||||
const auto skip = (size - useSize) / 2;
|
const auto skipx = (sizew - useSize) / 2;
|
||||||
return { x + skip, y + skip, useSize };
|
const auto skipy = (sizeh - useSize) / 2;
|
||||||
|
return { x + skipx, y + skipy, useSize };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::paintBlobs(Painter &p, int x, int y, int size, PanelMode mode) {
|
void Row::paintBlobs(
|
||||||
|
Painter &p,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
|
PanelMode mode) {
|
||||||
if (!_blobsAnimation) {
|
if (!_blobsAnimation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto size = sizew;
|
||||||
if (mode == PanelMode::Wide) {
|
if (mode == PanelMode::Wide) {
|
||||||
std::tie(x, y, size) = UserpicInWideMode(x, y, size);
|
std::tie(x, y, size) = UserpicInWideMode(x, y, sizew, sizeh);
|
||||||
}
|
}
|
||||||
const auto mutedByMe = (_state == State::MutedByMe);
|
const auto mutedByMe = (_state == State::MutedByMe);
|
||||||
const auto shift = QPointF(x + size / 2., y + size / 2.);
|
const auto shift = QPointF(x + size / 2., y + size / 2.);
|
||||||
|
@ -761,10 +795,12 @@ void Row::paintScaledUserpic(
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
int size,
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
PanelMode mode) {
|
PanelMode mode) {
|
||||||
|
auto size = sizew;
|
||||||
if (mode == PanelMode::Wide) {
|
if (mode == PanelMode::Wide) {
|
||||||
std::tie(x, y, size) = UserpicInWideMode(x, y, size);
|
std::tie(x, y, size) = UserpicInWideMode(x, y, sizew, sizeh);
|
||||||
}
|
}
|
||||||
if (!_blobsAnimation) {
|
if (!_blobsAnimation) {
|
||||||
peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
|
peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
|
||||||
|
@ -800,7 +836,8 @@ void Row::paintScaledUserpic(
|
||||||
|
|
||||||
auto Row::generatePaintUserpicCallback() -> PaintRoundImageCallback {
|
auto Row::generatePaintUserpicCallback() -> PaintRoundImageCallback {
|
||||||
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
return [=](Painter &p, int x, int y, int outerWidth, int size) {
|
||||||
paintComplexUserpic(p, x, y, outerWidth, size, PanelMode::Default);
|
const auto outer = outerWidth;
|
||||||
|
paintComplexUserpic(p, x, y, outer, size, size, PanelMode::Default);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,18 +846,20 @@ void Row::paintComplexUserpic(
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int outerWidth,
|
int outerWidth,
|
||||||
int size,
|
int sizew,
|
||||||
|
int sizeh,
|
||||||
PanelMode mode,
|
PanelMode mode,
|
||||||
bool selected) {
|
bool selected) {
|
||||||
if (mode == PanelMode::Wide) {
|
if (mode == PanelMode::Wide) {
|
||||||
if (paintVideo(p, x, y, size, mode)) {
|
if (paintVideo(p, x, y, sizew, sizeh, mode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_delegate->rowPaintWideBackground(p, selected);
|
_delegate->rowPaintWideBackground(p, selected);
|
||||||
paintRipple(p, x, y, outerWidth);
|
paintRipple(p, x, y, outerWidth);
|
||||||
}
|
}
|
||||||
paintBlobs(p, x, y, size, mode);
|
paintBlobs(p, x, y, sizew, sizeh, mode);
|
||||||
if (mode == PanelMode::Default && paintVideo(p, x, y, size, mode)) {
|
if (mode == PanelMode::Default
|
||||||
|
&& paintVideo(p, x, y, sizew, sizeh, mode)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
paintScaledUserpic(
|
paintScaledUserpic(
|
||||||
|
@ -829,7 +868,8 @@ void Row::paintComplexUserpic(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
outerWidth,
|
outerWidth,
|
||||||
size,
|
sizew,
|
||||||
|
sizeh,
|
||||||
mode);
|
mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1826,7 +1866,7 @@ void MembersController::rowPaintIcon(
|
||||||
void MembersController::rowPaintWideBackground(Painter &p, bool selected) {
|
void MembersController::rowPaintWideBackground(Painter &p, bool selected) {
|
||||||
(selected ? _wideRoundRectSelected : _wideRoundRect).paint(
|
(selected ? _wideRoundRectSelected : _wideRoundRect).paint(
|
||||||
p,
|
p,
|
||||||
{ QPoint(), st::groupCallNarrowSize });
|
{ QPoint(st::groupCallNarrowSkip, 0), st::groupCallNarrowSize });
|
||||||
}
|
}
|
||||||
|
|
||||||
int MembersController::customRowHeight() {
|
int MembersController::customRowHeight() {
|
||||||
|
@ -1840,12 +1880,14 @@ void MembersController::customRowPaint(
|
||||||
bool selected) {
|
bool selected) {
|
||||||
const auto real = static_cast<Row*>(row.get());
|
const auto real = static_cast<Row*>(row.get());
|
||||||
const auto width = st::groupCallNarrowSize.width();
|
const auto width = st::groupCallNarrowSize.width();
|
||||||
|
const auto height = st::groupCallNarrowSize.height();
|
||||||
real->paintComplexUserpic(
|
real->paintComplexUserpic(
|
||||||
p,
|
p,
|
||||||
0,
|
st::groupCallNarrowSkip,
|
||||||
0,
|
0,
|
||||||
width,
|
width,
|
||||||
width,
|
width,
|
||||||
|
height,
|
||||||
PanelMode::Wide,
|
PanelMode::Wide,
|
||||||
selected);
|
selected);
|
||||||
}
|
}
|
||||||
|
@ -1854,7 +1896,9 @@ bool MembersController::customRowSelectionPoint(
|
||||||
not_null<PeerListRow*> row,
|
not_null<PeerListRow*> row,
|
||||||
int x,
|
int x,
|
||||||
int y) {
|
int y) {
|
||||||
return y < st::groupCallNarrowSize.height();
|
return x >= st::groupCallNarrowSkip
|
||||||
|
&& x < st::groupCallNarrowSkip + st::groupCallNarrowSize.width()
|
||||||
|
&& y < st::groupCallNarrowSize.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
Fn<QImage()> MembersController::customRowRippleMaskGenerator() {
|
Fn<QImage()> MembersController::customRowRippleMaskGenerator() {
|
||||||
|
@ -1973,7 +2017,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|
||||||
const auto participant = real->participantByEndpoint(pinnedEndpoint);
|
const auto participant = real->participantByEndpoint(pinnedEndpoint);
|
||||||
if (participant && participant->peer == participantPeer) {
|
if (participant && participant->peer == participantPeer) {
|
||||||
result->addAction(
|
result->addAction(
|
||||||
tr::lng_group_call_context_unpin_video(tr::now),
|
tr::lng_group_call_context_unpin_camera(tr::now),
|
||||||
[=] { _call->pinVideoEndpoint(std::string()); });
|
[=] { _call->pinVideoEndpoint(std::string()); });
|
||||||
} else {
|
} else {
|
||||||
const auto &participants = real->participants();
|
const auto &participants = real->participants();
|
||||||
|
@ -1992,7 +2036,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|
||||||
: camera);
|
: camera);
|
||||||
};
|
};
|
||||||
result->addAction(
|
result->addAction(
|
||||||
tr::lng_group_call_context_pin_video(tr::now),
|
tr::lng_group_call_context_pin_camera(tr::now),
|
||||||
callback);
|
callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2292,27 +2336,61 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_canAddMembers.value(
|
rpl::combine(
|
||||||
) | rpl::start_with_next([=](bool can) {
|
_canAddMembers.value(),
|
||||||
|
_mode.value()
|
||||||
|
) | rpl::start_with_next([=](bool can, PanelMode mode) {
|
||||||
|
const auto old = _addMemberButton.current();
|
||||||
|
delete old;
|
||||||
if (!can) {
|
if (!can) {
|
||||||
delete _addMemberButton.current();
|
if (old) {
|
||||||
_addMemberButton = nullptr;
|
_addMemberButton = nullptr;
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
return;
|
}
|
||||||
} else if (_addMemberButton.current()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto addMember = Settings::CreateButton(
|
auto addMember = (Ui::AbstractButton*)nullptr;
|
||||||
this,
|
auto wrap = [&]() -> object_ptr<Ui::RpWidget> {
|
||||||
tr::lng_group_call_invite(),
|
if (mode == PanelMode::Default) {
|
||||||
st::groupCallAddMember,
|
auto result = Settings::CreateButton(
|
||||||
&st::groupCallAddMemberIcon,
|
this,
|
||||||
st::groupCallAddMemberIconLeft);
|
tr::lng_group_call_invite(),
|
||||||
|
st::groupCallAddMember,
|
||||||
|
&st::groupCallAddMemberIcon,
|
||||||
|
st::groupCallAddMemberIconLeft,
|
||||||
|
&st::groupCallMemberInactiveIcon);
|
||||||
|
addMember = result.data();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
auto result = object_ptr<Ui::RpWidget>(_layout.get());
|
||||||
|
const auto skip = st::groupCallNarrowSkip;
|
||||||
|
const auto fullwidth = st::groupCallNarrowSize.width()
|
||||||
|
+ 2 * skip;
|
||||||
|
const auto fullheight = st::groupCallNarrowAddMember.height
|
||||||
|
+ st::groupCallNarrowRowSkip;
|
||||||
|
result->resize(fullwidth, fullheight);
|
||||||
|
const auto button = Ui::CreateChild<Ui::RoundButton>(
|
||||||
|
result.data(),
|
||||||
|
rpl::single(QString()),
|
||||||
|
st::groupCallNarrowAddMember);
|
||||||
|
button->move(skip, 0);
|
||||||
|
const auto width = fullwidth - 2 * skip;
|
||||||
|
button->setFullWidth(width);
|
||||||
|
Settings::AddButtonIcon(
|
||||||
|
button,
|
||||||
|
&st::groupCallAddMemberIcon,
|
||||||
|
(width - st::groupCallAddMemberIcon.width()) / 2,
|
||||||
|
&st::groupCallMemberInactiveIcon);
|
||||||
|
addMember = button;
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
addMember->show();
|
addMember->show();
|
||||||
addMember->addClickHandler([=] { // TODO throttle(ripple duration)
|
addMember->clicks(
|
||||||
_addMemberRequests.fire({});
|
) | rpl::to_empty | rpl::start_to_stream(
|
||||||
});
|
_addMemberRequests,
|
||||||
_addMemberButton = _layout->insert(1, std::move(addMember));
|
addMember->lifetime());
|
||||||
|
_addMemberButton = wrap.data();
|
||||||
|
_layout->insert(1, std::move(wrap));
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ private:
|
||||||
std::unique_ptr<PeerListController> _listController;
|
std::unique_ptr<PeerListController> _listController;
|
||||||
not_null<Ui::VerticalLayout*> _layout;
|
not_null<Ui::VerticalLayout*> _layout;
|
||||||
const not_null<Ui::RpWidget*> _pinnedVideo;
|
const not_null<Ui::RpWidget*> _pinnedVideo;
|
||||||
rpl::variable<Ui::SettingsButton*> _addMemberButton = nullptr;
|
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||||
ListWidget *_list = nullptr;
|
ListWidget *_list = nullptr;
|
||||||
rpl::event_stream<> _addMemberRequests;
|
rpl::event_stream<> _addMemberRequests;
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ constexpr auto kRecordingAnimationDuration = crl::time(1200);
|
||||||
constexpr auto kRecordingOpacity = 0.6;
|
constexpr auto kRecordingOpacity = 0.6;
|
||||||
constexpr auto kStartNoConfirmation = TimeId(10);
|
constexpr auto kStartNoConfirmation = TimeId(10);
|
||||||
constexpr auto kControlsBackgroundOpacity = 0.8;
|
constexpr auto kControlsBackgroundOpacity = 0.8;
|
||||||
|
constexpr auto kOverrideActiveColorBgAlpha = 236;
|
||||||
|
|
||||||
class InviteController final : public ParticipantsBoxController {
|
class InviteController final : public ParticipantsBoxController {
|
||||||
public:
|
public:
|
||||||
|
@ -713,8 +714,21 @@ void Panel::refreshLeftButton() {
|
||||||
}
|
}
|
||||||
const auto raw = _callShare ? _callShare.data() : _settings.data();
|
const auto raw = _callShare ? _callShare.data() : _settings.data();
|
||||||
raw->show();
|
raw->show();
|
||||||
raw->setColorOverrides(_mute->colorOverrides());
|
|
||||||
|
|
||||||
|
auto overrides = _mute->colorOverrides();
|
||||||
|
raw->setColorOverrides(rpl::duplicate(overrides));
|
||||||
|
|
||||||
|
auto toggleableOverrides = [&](rpl::producer<bool> active) {
|
||||||
|
return rpl::combine(
|
||||||
|
std::move(active),
|
||||||
|
rpl::duplicate(overrides)
|
||||||
|
) | rpl::map([](bool active, Ui::CallButtonColors colors) {
|
||||||
|
if (active && colors.bg) {
|
||||||
|
colors.bg->setAlpha(kOverrideActiveColorBgAlpha);
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
});
|
||||||
|
};
|
||||||
if (!_video) {
|
if (!_video) {
|
||||||
_video.create(
|
_video.create(
|
||||||
widget(),
|
widget(),
|
||||||
|
@ -725,7 +739,12 @@ void Panel::refreshLeftButton() {
|
||||||
_call->toggleVideo(!_call->isSharingCamera());
|
_call->toggleVideo(!_call->isSharingCamera());
|
||||||
});
|
});
|
||||||
_video->setText(tr::lng_group_call_video());
|
_video->setText(tr::lng_group_call_video());
|
||||||
_video->setColorOverrides(_mute->colorOverrides());
|
_video->setColorOverrides(
|
||||||
|
toggleableOverrides(_call->isSharingCameraValue()));
|
||||||
|
_call->isSharingCameraValue(
|
||||||
|
) | rpl::start_with_next([=](bool sharing) {
|
||||||
|
_video->setProgress(sharing ? 1. : 0.);
|
||||||
|
}, _video->lifetime());
|
||||||
}
|
}
|
||||||
if (!_screenShare) {
|
if (!_screenShare) {
|
||||||
_screenShare.create(widget(), st::groupCallScreenShareSmall);
|
_screenShare.create(widget(), st::groupCallScreenShareSmall);
|
||||||
|
@ -736,7 +755,12 @@ void Panel::refreshLeftButton() {
|
||||||
#endif // Q_OS_LINUX
|
#endif // Q_OS_LINUX
|
||||||
});
|
});
|
||||||
_screenShare->setText(tr::lng_group_call_screen_share());
|
_screenShare->setText(tr::lng_group_call_screen_share());
|
||||||
_screenShare->setColorOverrides(_mute->colorOverrides());
|
_screenShare->setColorOverrides(
|
||||||
|
toggleableOverrides(_call->isSharingScreenValue()));
|
||||||
|
_call->isSharingScreenValue(
|
||||||
|
) | rpl::start_with_next([=](bool sharing) {
|
||||||
|
_screenShare->setProgress(sharing ? 1. : 0.);
|
||||||
|
}, _screenShare->lifetime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,19 +1711,19 @@ void Panel::updateMembersGeometry() {
|
||||||
}
|
}
|
||||||
const auto desiredHeight = _members->desiredHeight();
|
const auto desiredHeight = _members->desiredHeight();
|
||||||
if (_mode == PanelMode::Wide) {
|
if (_mode == PanelMode::Wide) {
|
||||||
|
const auto skip = st::groupCallNarrowSkip;
|
||||||
|
const auto membersWidth = st::groupCallNarrowSize.width() + 2 * skip;
|
||||||
|
const auto top = st::groupCallWideVideoTop;
|
||||||
_members->setGeometry(
|
_members->setGeometry(
|
||||||
st::groupCallNarrowSkip,
|
|
||||||
0,
|
0,
|
||||||
st::groupCallNarrowSize.width(),
|
top,
|
||||||
|
membersWidth,
|
||||||
std::min(desiredHeight, widget()->height()));
|
std::min(desiredHeight, widget()->height()));
|
||||||
const auto pinnedLeft = st::groupCallNarrowSkip * 2
|
|
||||||
+ st::groupCallNarrowSize.width();
|
|
||||||
const auto pinnedTop = st::groupCallWideVideoTop;
|
|
||||||
_pinnedVideo->setGeometry(
|
_pinnedVideo->setGeometry(
|
||||||
pinnedLeft,
|
membersWidth,
|
||||||
pinnedTop,
|
top,
|
||||||
widget()->width() - pinnedLeft - st::groupCallNarrowSkip,
|
widget()->width() - membersWidth - skip,
|
||||||
widget()->height() - pinnedTop - st::groupCallNarrowSkip);
|
widget()->height() - top - skip);
|
||||||
} else {
|
} else {
|
||||||
const auto membersBottom = _videoMode.current()
|
const auto membersBottom = _videoMode.current()
|
||||||
? (widget()->height() - st::groupCallMembersBottomSkipSmall)
|
? (widget()->height() - st::groupCallMembersBottomSkipSmall)
|
||||||
|
|
|
@ -35,9 +35,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
object_ptr<Section> CreateSection(
|
object_ptr<Section> CreateSection(
|
||||||
Type type,
|
Type type,
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Window::SessionController*> controller) {
|
not_null<Window::SessionController*> controller) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::Main:
|
case Type::Main:
|
||||||
return object_ptr<Main>(parent, controller);
|
return object_ptr<Main>(parent, controller);
|
||||||
|
@ -74,8 +74,8 @@ void AddDivider(not_null<Ui::VerticalLayout*> container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDividerText(
|
void AddDividerText(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
rpl::producer<QString> text) {
|
rpl::producer<QString> text) {
|
||||||
container->add(object_ptr<Ui::DividerLabel>(
|
container->add(object_ptr<Ui::DividerLabel>(
|
||||||
container,
|
container,
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
@ -85,37 +85,49 @@ void AddDividerText(
|
||||||
st::settingsDividerLabelPadding));
|
st::settingsDividerLabelPadding));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_null<Ui::RpWidget*> AddButtonIcon(
|
||||||
|
not_null<Ui::AbstractButton*> button,
|
||||||
|
const style::icon *leftIcon,
|
||||||
|
int iconLeft,
|
||||||
|
const style::color *leftIconOver) {
|
||||||
|
const auto icon = Ui::CreateChild<Ui::RpWidget>(button.get());
|
||||||
|
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
icon->resize(leftIcon->size());
|
||||||
|
button->sizeValue(
|
||||||
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
icon->moveToLeft(
|
||||||
|
iconLeft ? iconLeft : st::settingsSectionIconLeft,
|
||||||
|
(size.height() - icon->height()) / 2,
|
||||||
|
size.width());
|
||||||
|
}, icon->lifetime());
|
||||||
|
icon->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Painter p(icon);
|
||||||
|
const auto width = icon->width();
|
||||||
|
const auto paintOver = (button->isOver() || button->isDown())
|
||||||
|
&& !button->isDisabled();
|
||||||
|
if (!paintOver) {
|
||||||
|
leftIcon->paint(p, QPoint(), width);
|
||||||
|
} else if (leftIconOver) {
|
||||||
|
leftIcon->paint(p, QPoint(), width, (*leftIconOver)->c);
|
||||||
|
} else {
|
||||||
|
leftIcon->paint(p, QPoint(), width, st::menuIconFgOver->c);
|
||||||
|
}
|
||||||
|
}, icon->lifetime());
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<Button> CreateButton(
|
object_ptr<Button> CreateButton(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
rpl::producer<QString> text,
|
rpl::producer<QString> text,
|
||||||
const style::SettingsButton &st,
|
const style::SettingsButton &st,
|
||||||
const style::icon *leftIcon,
|
const style::icon *leftIcon,
|
||||||
int iconLeft) {
|
int iconLeft,
|
||||||
|
const style::color *leftIconOver) {
|
||||||
auto result = object_ptr<Button>(parent, std::move(text), st);
|
auto result = object_ptr<Button>(parent, std::move(text), st);
|
||||||
const auto button = result.data();
|
const auto button = result.data();
|
||||||
if (leftIcon) {
|
if (leftIcon) {
|
||||||
const auto icon = Ui::CreateChild<Ui::RpWidget>(button);
|
AddButtonIcon(button, leftIcon, iconLeft, leftIconOver);
|
||||||
icon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
icon->resize(leftIcon->size());
|
|
||||||
button->sizeValue(
|
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
|
||||||
icon->moveToLeft(
|
|
||||||
iconLeft ? iconLeft : st::settingsSectionIconLeft,
|
|
||||||
(size.height() - icon->height()) / 2,
|
|
||||||
size.width());
|
|
||||||
}, icon->lifetime());
|
|
||||||
icon->paintRequest(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
Painter p(icon);
|
|
||||||
const auto width = icon->width();
|
|
||||||
const auto paintOver = (button->isOver() || button->isDown())
|
|
||||||
&& !button->isDisabled();
|
|
||||||
if (paintOver) {
|
|
||||||
leftIcon->paint(p, QPoint(), width, st::menuIconFgOver->c);
|
|
||||||
} else {
|
|
||||||
leftIcon->paint(p, QPoint(), width);
|
|
||||||
}
|
|
||||||
}, icon->lifetime());
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Ui {
|
||||||
class VerticalLayout;
|
class VerticalLayout;
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
class SettingsButton;
|
class SettingsButton;
|
||||||
|
class AbstractButton;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -70,12 +71,18 @@ void AddDivider(not_null<Ui::VerticalLayout*> container);
|
||||||
void AddDividerText(
|
void AddDividerText(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
rpl::producer<QString> text);
|
rpl::producer<QString> text);
|
||||||
|
not_null<Ui::RpWidget*> AddButtonIcon(
|
||||||
|
not_null<Ui::AbstractButton*> button,
|
||||||
|
const style::icon *leftIcon,
|
||||||
|
int iconLeft,
|
||||||
|
const style::color *leftIconOver);
|
||||||
object_ptr<Button> CreateButton(
|
object_ptr<Button> CreateButton(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
rpl::producer<QString> text,
|
rpl::producer<QString> text,
|
||||||
const style::SettingsButton &st,
|
const style::SettingsButton &st,
|
||||||
const style::icon *leftIcon = nullptr,
|
const style::icon *leftIcon = nullptr,
|
||||||
int iconLeft = 0);
|
int iconLeft = 0,
|
||||||
|
const style::color *leftIconOver = nullptr);
|
||||||
not_null<Button*> AddButton(
|
not_null<Button*> AddButton(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
rpl::producer<QString> text,
|
rpl::producer<QString> text,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6ee9e983b8eebceb2603633c12d4cf2b973be046
|
Subproject commit 5c950149f53f109dbac37bde8b1144234e7c3c9a
|
|
@ -1 +1 @@
|
||||||
Subproject commit e1b96399d9031c4ef0354631e6bb375029d29d9f
|
Subproject commit df721be3fa14a27dfc230d2e3c42bb1a7c9d0617
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3c1866f52d88f9430341f9a9f1ed3dbbb3b794ea
|
Subproject commit b0c5d9220bb8f0fc614712167c8276504e60b224
|
Loading…
Reference in New Issue