mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 07:37:11 +02:00
Add tooltips for wide mode controls.
This commit is contained in:
parent
9a9430b5e1
commit
3f2b473287
11 changed files with 188 additions and 43 deletions
|
@ -1260,3 +1260,17 @@ groupCallTooltip: Tooltip(defaultTooltip) {
|
|||
textFg: groupCallMembersFg;
|
||||
textBorder: groupCallMembersBgOver;
|
||||
}
|
||||
groupCallNiceTooltip: ImportantTooltip(defaultImportantTooltip) {
|
||||
bg: importantTooltipBg;
|
||||
padding: margins(10px, 3px, 10px, 5px);
|
||||
radius: 4px;
|
||||
arrow: 4px;
|
||||
}
|
||||
groupCallNiceTooltipLabel: FlatLabel(defaultImportantTooltipLabel) {
|
||||
style: TextStyle(defaultTextStyle) {
|
||||
font: font(11px);
|
||||
linkFont: font(11px);
|
||||
linkFontOver: font(11px underline);
|
||||
}
|
||||
}
|
||||
groupCallNiceTooltipTop: 4px;
|
||||
|
|
|
@ -500,7 +500,6 @@ rpl::producer<bool> GroupCall::canManageValue() const {
|
|||
void GroupCall::toggleVideo(bool active) {
|
||||
if (!_instance
|
||||
|| !_id
|
||||
|| (active && mutedByAdmin())
|
||||
|| (!active && !_cameraOutgoing)) {
|
||||
return;
|
||||
}
|
||||
|
@ -513,7 +512,6 @@ void GroupCall::toggleVideo(bool active) {
|
|||
void GroupCall::toggleScreenSharing(std::optional<QString> uniqueId) {
|
||||
if (!_instance
|
||||
|| !_id
|
||||
|| (uniqueId && mutedByAdmin())
|
||||
|| (!uniqueId && !_screenOutgoing)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/dropdown_menu.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "ui/chat/group_call_bar.h"
|
||||
#include "ui/layers/layer_manager.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
|
@ -45,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/peer_lists_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "base/qt_signal_producer.h"
|
||||
#include "base/timer_rpl.h"
|
||||
#include "app.h"
|
||||
#include "apiwrap.h" // api().kickParticipant.
|
||||
|
@ -1792,6 +1794,7 @@ bool Panel::updateMode() {
|
|||
_call->pinVideoEndpoint({});
|
||||
}
|
||||
refreshVideoButtons(wide);
|
||||
_niceTooltip.destroy();
|
||||
_mode = mode;
|
||||
if (_title) {
|
||||
_title->setTextColorOverride(wide
|
||||
|
@ -1983,33 +1986,111 @@ void Panel::setupControlsBackgroundWide() {
|
|||
trackControls(true);
|
||||
}
|
||||
|
||||
template <typename WidgetPointer>
|
||||
void Panel::trackControl(WidgetPointer &widget, rpl::lifetime &lifetime) {
|
||||
if (widget) {
|
||||
const auto raw = &*widget;
|
||||
raw->events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
using Type = std::remove_cvref_t<decltype(*raw)>;
|
||||
constexpr auto mute = std::is_same_v<Type, Ui::CallMuteButton>;
|
||||
if (e->type() == QEvent::Enter) {
|
||||
auto &integration = Ui::Integration::Instance();
|
||||
if constexpr (mute) {
|
||||
integration.registerLeaveSubscription(raw->outer());
|
||||
} else {
|
||||
integration.registerLeaveSubscription(raw);
|
||||
}
|
||||
toggleWideControls(true);
|
||||
} else if (e->type() == QEvent::Leave) {
|
||||
auto &integration = Ui::Integration::Instance();
|
||||
if constexpr (mute) {
|
||||
integration.unregisterLeaveSubscription(raw->outer());
|
||||
} else {
|
||||
integration.unregisterLeaveSubscription(raw);
|
||||
}
|
||||
toggleWideControls(false);
|
||||
}
|
||||
}, lifetime);
|
||||
void Panel::trackControl(Ui::RpWidget *widget, rpl::lifetime &lifetime) {
|
||||
if (!widget) {
|
||||
return;
|
||||
}
|
||||
widget->events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::Enter) {
|
||||
trackControlOver(widget, true);
|
||||
} else if (e->type() == QEvent::Leave) {
|
||||
trackControlOver(widget, false);
|
||||
}
|
||||
}, lifetime);
|
||||
}
|
||||
|
||||
void Panel::trackControlOver(not_null<Ui::RpWidget*> control, bool over) {
|
||||
if (_niceTooltip) {
|
||||
_niceTooltip.release()->toggleAnimated(false);
|
||||
}
|
||||
if (over) {
|
||||
Ui::Integration::Instance().registerLeaveSubscription(control);
|
||||
showNiceTooltip(control);
|
||||
} else {
|
||||
Ui::Integration::Instance().unregisterLeaveSubscription(control);
|
||||
}
|
||||
toggleWideControls(over);
|
||||
}
|
||||
|
||||
void Panel::showNiceTooltip(not_null<Ui::RpWidget*> control) {
|
||||
auto text = [&]() -> rpl::producer<QString> {
|
||||
if (control == _screenShare.data()) {
|
||||
if (_call->mutedByAdmin()) {
|
||||
return nullptr;
|
||||
}
|
||||
return tr::lng_group_call_tooltip_screen();
|
||||
} else if (control == _video.data()) {
|
||||
if (_call->mutedByAdmin()) {
|
||||
return nullptr;
|
||||
}
|
||||
return _call->isSharingCameraValue(
|
||||
) | rpl::map([=](bool sharing) {
|
||||
return sharing
|
||||
? tr::lng_group_call_tooltip_camera_off()
|
||||
: tr::lng_group_call_tooltip_camera();
|
||||
}) | rpl::flatten_latest();
|
||||
} else if (control == _settings.data()) {
|
||||
return tr::lng_group_call_settings();
|
||||
} else if (control == _mute->outer()) {
|
||||
return MuteButtonTooltip(_call);
|
||||
} else if (control == _hangup.data()) {
|
||||
return tr::lng_group_call_leave();
|
||||
}
|
||||
return rpl::producer<QString>();
|
||||
}();
|
||||
if (!text
|
||||
|| _wideControlsAnimation.animating()
|
||||
|| !_wideControlsShown) {
|
||||
return;
|
||||
}
|
||||
_niceTooltip.create(
|
||||
widget().get(),
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
widget().get(),
|
||||
std::move(text),
|
||||
st::groupCallNiceTooltipLabel),
|
||||
st::groupCallNiceTooltip);
|
||||
const auto tooltip = _niceTooltip.data();
|
||||
const auto weak = QPointer<QWidget>(tooltip);
|
||||
const auto destroy = [=] {
|
||||
delete weak.data();
|
||||
};
|
||||
tooltip->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
tooltip->setHiddenCallback(destroy);
|
||||
base::qt_signal_producer(
|
||||
control.get(),
|
||||
&QObject::destroyed
|
||||
) | rpl::start_with_next(destroy, tooltip->lifetime());
|
||||
|
||||
const auto geometry = control->geometry();
|
||||
const auto countPosition = [=](QSize size) {
|
||||
const auto strong = weak.data();
|
||||
if (!strong) {
|
||||
return QPoint();
|
||||
}
|
||||
const auto top = geometry.y()
|
||||
- st::groupCallNiceTooltipTop
|
||||
- size.height();
|
||||
const auto middle = geometry.center().x();
|
||||
const auto back = _controlsBackgroundWide.data();
|
||||
if (size.width() >= _viewport->widget()->width()) {
|
||||
return QPoint(_viewport->widget()->x(), top);
|
||||
} else if (back && size.width() >= back->width()) {
|
||||
return QPoint(
|
||||
back->x() - (size.width() - back->width()) / 2,
|
||||
top);
|
||||
} else if (back && (middle - back->x() < size.width() / 2)) {
|
||||
return QPoint(back->x(), top);
|
||||
} else if (back
|
||||
&& (back->x() + back->width() - middle < size.width() / 2)) {
|
||||
return QPoint(back->x() + back->width() - size.width(), top);
|
||||
} else {
|
||||
return QPoint(middle - size.width() / 2, top);
|
||||
}
|
||||
};
|
||||
tooltip->pointAt(geometry, RectPart::Top, countPosition);
|
||||
tooltip->toggleAnimated(true);
|
||||
}
|
||||
|
||||
void Panel::trackControls(bool track) {
|
||||
|
@ -2032,7 +2113,7 @@ void Panel::trackControls(bool track) {
|
|||
const auto trackOne = [=](auto &&widget) {
|
||||
trackControl(widget, _trackControlsOverStateLifetime);
|
||||
};
|
||||
trackOne(_mute);
|
||||
trackOne(_mute->outer());
|
||||
trackOne(_video);
|
||||
trackOne(_screenShare);
|
||||
trackOne(_wideMenu);
|
||||
|
@ -2106,13 +2187,13 @@ void Panel::updateButtonsGeometry() {
|
|||
const auto skip = st::groupCallButtonSkipSmall;
|
||||
const auto fullWidth = (_video->width() + skip)
|
||||
+ (_screenShare->width() + skip)
|
||||
+ muteSize
|
||||
+ (muteSize + skip)
|
||||
+ (_settings ->width() + skip)
|
||||
+ _hangup->width() + skip;
|
||||
+ _hangup->width();
|
||||
const auto membersSkip = st::groupCallNarrowSkip;
|
||||
const auto membersWidth = st::groupCallNarrowMembersWidth
|
||||
+ 2 * membersSkip;
|
||||
auto left = (widget()->width()
|
||||
auto left = membersSkip + (widget()->width()
|
||||
- membersWidth
|
||||
- membersSkip
|
||||
- fullWidth) / 2;
|
||||
|
|
|
@ -26,6 +26,7 @@ class GroupCall;
|
|||
|
||||
namespace Ui {
|
||||
class AbstractButton;
|
||||
class ImportantTooltip;
|
||||
class DropdownMenu;
|
||||
class CallButton;
|
||||
class CallMuteButton;
|
||||
|
@ -102,8 +103,9 @@ private:
|
|||
void enlargeVideo();
|
||||
void minimizeVideo();
|
||||
|
||||
template <typename WidgetPointer>
|
||||
void trackControl(WidgetPointer &widget, rpl::lifetime &lifetime);
|
||||
void trackControl(Ui::RpWidget *widget, rpl::lifetime &lifetime);
|
||||
void trackControlOver(not_null<Ui::RpWidget*> control, bool over);
|
||||
void showNiceTooltip(not_null<Ui::RpWidget*> control);
|
||||
|
||||
bool updateMode();
|
||||
void updateControlsGeometry();
|
||||
|
@ -191,6 +193,7 @@ private:
|
|||
object_ptr<Ui::CallButton> _screenShare = { nullptr };
|
||||
std::unique_ptr<Ui::CallMuteButton> _mute;
|
||||
object_ptr<Ui::CallButton> _hangup;
|
||||
object_ptr<Ui::ImportantTooltip> _niceTooltip = { nullptr };
|
||||
Fn<void()> _callShareLinkCallback;
|
||||
|
||||
rpl::lifetime _peerLifetime;
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/gl/gl_surface.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/cross_line.h"
|
||||
#include "data/data_group_call.h" // MuteButtonTooltip.
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_calls.h"
|
||||
|
||||
|
@ -603,4 +604,51 @@ QImage GenerateShadow(
|
|||
return result;
|
||||
}
|
||||
|
||||
rpl::producer<QString> MuteButtonTooltip(not_null<GroupCall*> call) {
|
||||
//return rpl::single(std::make_tuple(
|
||||
// (Data::GroupCall*)nullptr,
|
||||
// call->scheduleDate()
|
||||
//)) | rpl::then(call->real(
|
||||
//) | rpl::map([](not_null<Data::GroupCall*> real) {
|
||||
// using namespace rpl::mappers;
|
||||
// return real->scheduleDateValue(
|
||||
// ) | rpl::map([=](TimeId scheduleDate) {
|
||||
// return std::make_tuple(real.get(), scheduleDate);
|
||||
// });
|
||||
//}) | rpl::flatten_latest(
|
||||
//)) | rpl::map([=](
|
||||
// Data::GroupCall *real,
|
||||
// TimeId scheduleDate) -> rpl::producer<QString> {
|
||||
// if (scheduleDate) {
|
||||
// return rpl::combine(
|
||||
// call->canManageValue(),
|
||||
// (real
|
||||
// ? real->scheduleStartSubscribedValue()
|
||||
// : rpl::single(false))
|
||||
// ) | rpl::map([](bool canManage, bool subscribed) {
|
||||
// return canManage
|
||||
// ? tr::lng_group_call_start_now()
|
||||
// : subscribed
|
||||
// ? tr::lng_group_call_cancel_reminder()
|
||||
// : tr::lng_group_call_set_reminder();
|
||||
// }) | rpl::flatten_latest();
|
||||
// }
|
||||
return call->mutedValue(
|
||||
) | rpl::map([](MuteState muted) {
|
||||
switch (muted) {
|
||||
case MuteState::Active:
|
||||
case MuteState::PushToTalk:
|
||||
return tr::lng_group_call_you_are_live();
|
||||
case MuteState::ForceMuted:
|
||||
return tr::lng_group_call_tooltip_force_muted();
|
||||
case MuteState::RaisedHand:
|
||||
return tr::lng_group_call_tooltip_raised_hand();
|
||||
case MuteState::Muted:
|
||||
return tr::lng_group_call_tooltip_microphone();
|
||||
}
|
||||
Unexpected("Value in MuteState in showNiceTooltip.");
|
||||
}) | rpl::flatten_latest();
|
||||
//}) | rpl::flatten_latest();
|
||||
}
|
||||
|
||||
} // namespace Calls::Group
|
||||
|
|
|
@ -23,6 +23,7 @@ struct ChosenRenderer;
|
|||
} // namespace Ui
|
||||
|
||||
namespace Calls {
|
||||
class GroupCall;
|
||||
struct VideoEndpoint;
|
||||
struct VideoPinToggle;
|
||||
struct VideoQualityRequest;
|
||||
|
@ -158,4 +159,7 @@ private:
|
|||
int bottomAlpha,
|
||||
QColor color = QColor(0, 0, 0));
|
||||
|
||||
[[nodiscard]] rpl::producer<QString> MuteButtonTooltip(
|
||||
not_null<GroupCall*> call);
|
||||
|
||||
} // namespace Calls::Group
|
||||
|
|
|
@ -1068,10 +1068,6 @@ rpl::producer<Qt::MouseButton> CallMuteButton::clicks() {
|
|||
});
|
||||
}
|
||||
|
||||
rpl::producer<not_null<QEvent*>> CallMuteButton::events() const {
|
||||
return _content->events();
|
||||
}
|
||||
|
||||
QSize CallMuteButton::innerSize() const {
|
||||
return innerGeometry().size();
|
||||
}
|
||||
|
@ -1169,7 +1165,7 @@ rpl::producer<CallButtonColors> CallMuteButton::colorOverrides() const {
|
|||
return _colorOverrides.events();
|
||||
}
|
||||
|
||||
not_null<QWidget*> CallMuteButton::outer() const {
|
||||
not_null<RpWidget*> CallMuteButton::outer() const {
|
||||
return _content.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ 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;
|
||||
|
@ -83,7 +82,7 @@ public:
|
|||
void raise();
|
||||
void lower();
|
||||
|
||||
[[nodiscard]] not_null<QWidget*> outer() const;
|
||||
[[nodiscard]] not_null<RpWidget*> outer() const;
|
||||
[[nodiscard]] rpl::producer<CallButtonColors> colorOverrides() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime();
|
||||
|
|
2
Telegram/ThirdParty/tgcalls
vendored
2
Telegram/ThirdParty/tgcalls
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 11cd08b14206a2ce3669cebafb6e693a30ef14ab
|
||||
Subproject commit 19543aaf43d97e254f9b379cc3bc77491009f9d4
|
|
@ -91,6 +91,8 @@ PRIVATE
|
|||
# iOS / macOS
|
||||
platform/darwin/DarwinInterface.h
|
||||
platform/darwin/DarwinInterface.mm
|
||||
platform/darwin/DarwinVideoSource.h
|
||||
platform/darwin/DarwinVideoSource.mm
|
||||
platform/darwin/DesktopCaptureSourceView.h
|
||||
platform/darwin/DesktopCaptureSourceView.mm
|
||||
platform/darwin/DesktopSharingCapturer.h
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8fbeb7f5032e588dfd134c9fe80e1880f888f12f
|
||||
Subproject commit f475fe28e47af4408bc96ba63e63f599c02538ca
|
Loading…
Add table
Reference in a new issue