1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "base/weak_ptr.h" 11 #include "base/timer.h" 12 #include "base/flags.h" 13 #include "base/object_ptr.h" 14 #include "calls/group/calls_group_call.h" 15 #include "calls/group/calls_group_common.h" 16 #include "calls/group/calls_choose_join_as.h" 17 #include "calls/group/ui/desktop_capture_choose_source.h" 18 #include "ui/effects/animations.h" 19 #include "ui/gl/gl_window.h" 20 #include "ui/rp_widget.h" 21 22 class Image; 23 24 namespace Data { 25 class PhotoMedia; 26 class CloudImageView; 27 class GroupCall; 28 } // namespace Data 29 30 namespace Ui { 31 class BoxContent; 32 enum class LayerOption; 33 using LayerOptions = base::flags<LayerOption>; 34 class AbstractButton; 35 class ImportantTooltip; 36 class DropdownMenu; 37 class CallButton; 38 class CallMuteButton; 39 class IconButton; 40 class FlatLabel; 41 class RpWidget; 42 template <typename Widget> 43 class FadeWrap; 44 template <typename Widget> 45 class PaddingWrap; 46 class ScrollArea; 47 class GenericBox; 48 class LayerManager; 49 class GroupCallScheduledLeft; 50 namespace Toast { 51 class Instance; 52 } // namespace Toast 53 namespace Platform { 54 class TitleControls; 55 } // namespace Platform 56 } // namespace Ui 57 58 namespace style { 59 struct CallSignalBars; 60 struct CallBodyLayout; 61 } // namespace style 62 63 namespace Calls::Group { 64 65 class Toasts; 66 class Members; 67 class Viewport; 68 enum class PanelMode; 69 enum class StickedTooltip; 70 class MicLevelTester; 71 72 class Panel final : private Ui::DesktopCapture::ChooseSourceDelegate { 73 public: 74 Panel(not_null<GroupCall*> call); 75 ~Panel(); 76 77 [[nodiscard]] not_null<GroupCall*> call() const; 78 [[nodiscard]] bool isActive() const; 79 80 void showToast(TextWithEntities &&text, crl::time duration = 0); 81 void showBox(object_ptr<Ui::BoxContent> box); 82 void showBox( 83 object_ptr<Ui::BoxContent> box, 84 Ui::LayerOptions options, 85 anim::type animated = anim::type::normal); 86 87 void minimize(); 88 void close(); 89 void showAndActivate(); 90 void closeBeforeDestroy(); 91 92 rpl::lifetime &lifetime(); 93 94 private: 95 using State = GroupCall::State; 96 struct ControlsBackgroundNarrow; 97 98 enum class NiceTooltipType { 99 Normal, 100 Sticked, 101 }; 102 enum class StickedTooltipHide { 103 Unavailable, 104 Activated, 105 Discarded, 106 }; 107 108 [[nodiscard]] not_null<Ui::RpWindow*> window() const; 109 [[nodiscard]] not_null<Ui::RpWidget*> widget() const; 110 111 [[nodiscard]] PanelMode mode() const; 112 113 void paint(QRect clip); 114 115 void initWindow(); 116 void initWidget(); 117 void initControls(); 118 void initShareAction(); 119 void initLayout(); 120 void initGeometry(); 121 void setupScheduledLabels(rpl::producer<TimeId> date); 122 void setupMembers(); 123 void setupVideo(not_null<Viewport*> viewport); 124 void setupRealMuteButtonState(not_null<Data::GroupCall*> real); 125 126 bool handleClose(); 127 void startScheduledNow(); 128 void trackControls(bool track); 129 void raiseControls(); 130 void enlargeVideo(); 131 void minimizeVideo(); 132 133 void trackControl(Ui::RpWidget *widget, rpl::lifetime &lifetime); 134 void trackControlOver(not_null<Ui::RpWidget*> control, bool over); 135 void showNiceTooltip( 136 not_null<Ui::RpWidget*> control, 137 NiceTooltipType type = NiceTooltipType::Normal); 138 void showStickedTooltip(); 139 void hideStickedTooltip(StickedTooltipHide hide); 140 void hideStickedTooltip(StickedTooltip type, StickedTooltipHide hide); 141 void hideNiceTooltip(); 142 143 bool updateMode(); 144 void updateControlsGeometry(); 145 void updateButtonsGeometry(); 146 void updateTooltipGeometry(); 147 void updateButtonsStyles(); 148 void updateMembersGeometry(); 149 void refreshControlsBackground(); 150 void setupControlsBackgroundWide(); 151 void setupControlsBackgroundNarrow(); 152 void showControls(); 153 void refreshLeftButton(); 154 void refreshVideoButtons( 155 std::optional<bool> overrideWideMode = std::nullopt); 156 void refreshTopButton(); 157 void toggleWideControls(bool shown); 158 void updateWideControlsVisibility(); 159 [[nodiscard]] bool videoButtonInNarrowMode() const; 160 161 void endCall(); 162 163 void showMainMenu(); 164 void chooseJoinAs(); 165 void chooseShareScreenSource(); 166 void screenSharingPrivacyRequest(); 167 void addMembers(); 168 void kickParticipant(not_null<PeerData*> participantPeer); 169 void kickParticipantSure(not_null<PeerData*> participantPeer); 170 [[nodiscard]] QRect computeTitleRect() const; 171 void refreshTitle(); 172 void refreshTitleGeometry(); 173 void setupRealCallViewers(); 174 void subscribeToChanges(not_null<Data::GroupCall*> real); 175 176 void migrate(not_null<ChannelData*> channel); 177 void subscribeToPeerChanges(); 178 179 QWidget *chooseSourceParent() override; 180 QString chooseSourceActiveDeviceId() override; 181 bool chooseSourceActiveWithAudio() override; 182 bool chooseSourceWithAudioSupported() override; 183 rpl::lifetime &chooseSourceInstanceLifetime() override; 184 void chooseSourceAccepted( 185 const QString &deviceId, 186 bool withAudio) override; 187 void chooseSourceStop() override; 188 189 const not_null<GroupCall*> _call; 190 not_null<PeerData*> _peer; 191 192 Ui::GL::Window _window; 193 const std::unique_ptr<Ui::LayerManager> _layerBg; 194 rpl::variable<PanelMode> _mode; 195 196 #ifndef Q_OS_MAC 197 std::unique_ptr<Ui::Platform::TitleControls> _controls; 198 #endif // !Q_OS_MAC 199 200 rpl::lifetime _callLifetime; 201 202 object_ptr<Ui::FlatLabel> _title = { nullptr }; 203 object_ptr<Ui::FlatLabel> _subtitle = { nullptr }; 204 object_ptr<Ui::AbstractButton> _recordingMark = { nullptr }; 205 object_ptr<Ui::IconButton> _menuToggle = { nullptr }; 206 object_ptr<Ui::DropdownMenu> _menu = { nullptr }; 207 rpl::variable<bool> _wideMenuShown = false; 208 object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr }; 209 object_ptr<Members> _members = { nullptr }; 210 std::unique_ptr<Viewport> _viewport; 211 rpl::lifetime _trackControlsLifetime; 212 rpl::lifetime _trackControlsOverStateLifetime; 213 rpl::lifetime _trackControlsMenuLifetime; 214 object_ptr<Ui::FlatLabel> _startsIn = { nullptr }; 215 object_ptr<Ui::RpWidget> _countdown = { nullptr }; 216 std::shared_ptr<Ui::GroupCallScheduledLeft> _countdownData; 217 object_ptr<Ui::FlatLabel> _startsWhen = { nullptr }; 218 ChooseJoinAsProcess _joinAsProcess; 219 std::optional<QRect> _lastSmallGeometry; 220 std::optional<QRect> _lastLargeGeometry; 221 bool _lastLargeMaximized = false; 222 bool _showWideControls = false; 223 bool _trackControls = false; 224 bool _wideControlsShown = false; 225 Ui::Animations::Simple _wideControlsAnimation; 226 227 object_ptr<Ui::RpWidget> _controlsBackgroundWide = { nullptr }; 228 std::unique_ptr<ControlsBackgroundNarrow> _controlsBackgroundNarrow; 229 object_ptr<Ui::CallButton> _settings = { nullptr }; 230 object_ptr<Ui::CallButton> _wideMenu = { nullptr }; 231 object_ptr<Ui::CallButton> _callShare = { nullptr }; 232 object_ptr<Ui::CallButton> _video = { nullptr }; 233 object_ptr<Ui::CallButton> _screenShare = { nullptr }; 234 std::unique_ptr<Ui::CallMuteButton> _mute; 235 object_ptr<Ui::CallButton> _hangup; 236 object_ptr<Ui::ImportantTooltip> _niceTooltip = { nullptr }; 237 QPointer<Ui::IconButton> _stickedTooltipClose; 238 QPointer<Ui::RpWidget> _niceTooltipControl; 239 StickedTooltips _stickedTooltipsShown; 240 Fn<void()> _callShareLinkCallback; 241 242 const std::unique_ptr<Toasts> _toasts; 243 base::weak_ptr<Ui::Toast::Instance> _lastToast; 244 245 std::unique_ptr<MicLevelTester> _micLevelTester; 246 247 rpl::lifetime _peerLifetime; 248 249 }; 250 251 } // namespace Calls::Group 252