diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index eedca3a782..d1c5caeb92 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -200,7 +200,7 @@ namespace { w->notifyClearFast(); w->setupIntro(true); } - MTP::authed(0); + MTP::setAuthedId(0); Local::reset(); cSetOtherOnline(0); @@ -211,9 +211,8 @@ namespace { if (App::uploader()) App::uploader()->clear(); clearStorageImages(); if (auto w = wnd()) { - w->getTitle()->updateBackButton(); - w->updateTitleStatus(); - w->getTitle()->resizeEvent(0); + w->updateConnectingStatus(); + w->getTitle()->updateControlsVisibility(); } return true; } diff --git a/Telegram/SourceFiles/boxes/passcodebox.cpp b/Telegram/SourceFiles/boxes/passcodebox.cpp index 32ccd9e8af..d0ef9b754b 100644 --- a/Telegram/SourceFiles/boxes/passcodebox.cpp +++ b/Telegram/SourceFiles/boxes/passcodebox.cpp @@ -406,7 +406,7 @@ void PasscodeBox::onSave(bool force) { cSetPasscodeBadTries(0); Local::setPasscode(pwd.toUtf8()); App::wnd()->checkAutoLock(); - App::wnd()->getTitle()->showUpdateBtn(); + App::wnd()->getTitle()->updateControlsVisibility(); onClose(); } } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index ccf5631df6..6fcb663362 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3065,9 +3065,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) connect(&_sendActionStopTimer, SIGNAL(timeout()), this, SLOT(onCancelSendAction())); connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout())); if (audioCapture()) { - connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError())); - connect(audioCapture(), SIGNAL(onUpdate(quint16,qint32)), this, SLOT(onRecordUpdate(quint16,qint32))); - connect(audioCapture(), SIGNAL(onDone(QByteArray,VoiceWaveform,qint32)), this, SLOT(onRecordDone(QByteArray,VoiceWaveform,qint32))); + connect(audioCapture(), SIGNAL(error()), this, SLOT(onRecordError())); + connect(audioCapture(), SIGNAL(updated(quint16,qint32)), this, SLOT(onRecordUpdate(quint16,qint32))); + connect(audioCapture(), SIGNAL(done(QByteArray,VoiceWaveform,qint32)), this, SLOT(onRecordDone(QByteArray,VoiceWaveform,qint32))); } _updateHistoryItems.setSingleShot(true); @@ -5719,7 +5719,7 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) { } void HistoryWidget::stopRecording(bool send) { - audioCapture()->stop(send); + emit audioCapture()->stop(send); a_recordingLevel = anim::ivalue(0, 0); _a_recording.stop(); @@ -7411,7 +7411,7 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) { if (_replyForwardPressed && !_fieldBarCancel.isHidden()) { updateField(); } else if (_inRecord && cHasAudioCapture()) { - audioCapture()->start(); + emit audioCapture()->start(); _recording = _inField = true; updateControlsVisibility(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ff57653202..6e2fe177a1 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -77,11 +77,6 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window) , _api(new ApiWrap(this)) { setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight)); - if (!_mediaPlayer) { - _mediaPlayer = new Media::Player::Widget(this); - App::wnd()->getTitle()->playerButton()->installEventFilter(_mediaPlayer); - } - MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived)); _ptsWaiter.setRequesting(true); updateScrollColors(); @@ -128,7 +123,7 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window) } else { _history->show(); } - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); _topBar->hide(); _player->hidePlayer(); @@ -574,7 +569,7 @@ void MainWidget::noHider(HistoryHider *destroyed) { _history->showAnimated(Window::SlideDirection::FromRight, animationParams); } } - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); } else { if (_forwardConfirm) { _forwardConfirm->deleteLater(); @@ -611,7 +606,7 @@ void MainWidget::hiderLayer(HistoryHider *h) { resizeEvent(0); _dialogs->showAnimated(Window::SlideDirection::FromLeft, animationParams); } - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); } else { _hider->show(); resizeEvent(0); @@ -1549,7 +1544,6 @@ void MainWidget::ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId) { void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { if (audioId.type() == AudioMsgId::Type::Video) { - audioPlayer()->videoSoundProgress(audioId); return; } @@ -1559,8 +1553,8 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { playbackState.state = AudioPlayerStopped; audioPlayer()->clearStoppedAtStart(audioId); - DocumentData *audio = audioId.audio(); - QString filepath = audio->filepath(DocumentData::FilePathResolveSaveFromData); + auto document = audioId.audio(); + auto filepath = document->filepath(DocumentData::FilePathResolveSaveFromData); if (!filepath.isEmpty()) { if (documentIsValidMediaFile(filepath)) { psOpenFile(filepath); @@ -1583,14 +1577,12 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { } } - if (audioId.type() != AudioMsgId::Type::Video) { - if (auto item = App::histItemById(audioId.contextId())) { - Ui::repaintHistoryItem(item); - } - if (auto items = InlineBots::Layout::documentItems()) { - for (auto item : items->value(audioId.audio())) { - Ui::repaintInlineItem(item); - } + if (auto item = App::histItemById(audioId.contextId())) { + Ui::repaintHistoryItem(item); + } + if (auto items = InlineBots::Layout::documentItems()) { + for (auto item : items->value(audioId.audio())) { + Ui::repaintInlineItem(item); } } } @@ -2142,7 +2134,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show _dialogs->update(); } topBar()->showAll(); - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); } PeerData *MainWidget::ui_getPeerForMouseAction() { @@ -2264,7 +2256,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool orderWidgets(); - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); } void MainWidget::showWideSection(const Window::SectionMemento &memento) { @@ -2363,7 +2355,7 @@ void MainWidget::showWideSectionAnimated(const Window::SectionMemento *memento, orderWidgets(); - App::wnd()->getTitle()->updateBackButton(); + App::wnd()->getTitle()->updateControlsVisibility(); } bool MainWidget::stackIsEmpty() const { @@ -3285,8 +3277,9 @@ void MainWidget::mtpPing() { void MainWidget::start(const MTPUser &user) { int32 uid = user.c_user().vid.v; if (MTP::authedId() != uid) { - MTP::authed(uid); + MTP::setAuthedId(uid); Local::writeMtpData(); + App::wnd()->getTitle()->updateControlsVisibility(); } Local::readSavedPeers(); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 657f944a4b..c91029e515 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -137,7 +137,6 @@ class MainWidget : public TWidget, public RPCSender, private base::Subscriber { Q_OBJECT public: - MainWidget(MainWindow *window); void paintEvent(QPaintEvent *e) override; @@ -413,7 +412,6 @@ public: ~MainWidget(); signals: - void peerUpdated(PeerData *peer); void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars); void peerPhotoChanged(PeerData *peer); @@ -423,7 +421,6 @@ signals: void savedGifsUpdated(); public slots: - void webPagesUpdate(); void audioPlayProgress(const AudioMsgId &audioId); @@ -480,8 +477,6 @@ public slots: void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId, Ui::ShowWay way); void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId); -private slots: - void onDeletePhotoSure(); private: diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index cc3abdd4a4..14fbdb2d6c 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -515,7 +515,7 @@ void MainWindow::clearWidgets() { hideMediaview(); _mediaView->rpcClear(); } - title->updateBackButton(); + title->updateControlsVisibility(); updateGlobalMenu(); } @@ -548,7 +548,7 @@ void MainWindow::clearPasscode() { main->animShow(bg, true); } notifyUpdateAll(); - title->updateBackButton(); + title->updateControlsVisibility(); updateGlobalMenu(); } @@ -574,7 +574,7 @@ void MainWindow::setupPasscode(bool anim) { } _shouldLockAt = 0; notifyUpdateAll(); - title->updateBackButton(); + title->updateControlsVisibility(); updateGlobalMenu(); } @@ -620,7 +620,7 @@ void MainWindow::setupIntro(bool anim) { fixOrder(); - updateTitleStatus(); + updateConnectingStatus(); _delayedServiceMsgs.clear(); if (_serviceHistoryRequest) { @@ -673,11 +673,11 @@ void MainWindow::setupMain(bool anim, const MTPUser *self) { } else { MTP::send(MTPusers_GetUsers(MTP_vector(1, MTP_inputUserSelf())), main->rpcDone(&MainWidget::startFull)); } - title->resizeEvent(0); + title->updateControlsVisibility(); fixOrder(); - updateTitleStatus(); + updateConnectingStatus(); } void MainWindow::updateUnreadCounter() { @@ -713,12 +713,12 @@ void MainWindow::ui_hideSettingsAndLayer(ShowLayerOptions options) { void MainWindow::mtpStateChanged(int32 dc, int32 state) { if (dc == MTP::maindc()) { - updateTitleStatus(); + updateConnectingStatus(); Global::RefConnectionTypeChanged().notify(); } } -void MainWindow::updateTitleStatus() { +void MainWindow::updateConnectingStatus() { int32 state = MTP::dcstate(); if (state == MTP::ConnectingState || state == MTP::DisconnectedState || (state < 0 && state > -600)) { if (main || getms() > 5000 || _connecting) { @@ -726,7 +726,7 @@ void MainWindow::updateTitleStatus() { } } else if (state < 0) { showConnecting(lng_reconnecting(lt_count, ((-state) / 1000) + 1), lang(lng_reconnecting_try_now)); - QTimer::singleShot((-state) % 1000, this, SLOT(updateTitleStatus())); + QTimer::singleShot((-state) % 1000, this, SLOT(updateConnectingStatus())); } else { hideConnecting(); } @@ -853,28 +853,21 @@ void MainWindow::showConnecting(const QString &text, const QString &reconnect) { if (_connecting) { _connecting->set(text, reconnect); } else { - _connecting = new ConnectingWidget(this, text, reconnect); + _connecting.create(this, text, reconnect); _connecting->show(); resizeEvent(0); fixOrder(); } - if (settings) settings->update(); -} - -bool MainWindow::connectingVisible() const { - return _connecting && !_connecting->isHidden(); } void MainWindow::hideConnecting() { if (_connecting) { - _connecting->deleteLater(); - _connecting = 0; + _connecting.destroyDelayed(); } - if (settings) settings->update(); } bool MainWindow::doWeReadServerHistory() const { - return isActive(false) && main && (!settings || !settings->isVisible()) && main->doWeReadServerHistory(); + return isActive(false) && main && !Ui::isLayerShown() && main->doWeReadServerHistory(); } void MainWindow::checkHistoryActivation() { diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index edd20a7945..bc28dada08 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -175,10 +175,6 @@ public: MainWidget *mainWidget(); PasscodeWidget *passcodeWidget(); - void showConnecting(const QString &text, const QString &reconnect = QString()); - void hideConnecting(); - bool connectingVisible() const; - void showPhoto(const PhotoOpenClickHandler *lnk, HistoryItem *item = 0); void showPhoto(PhotoData *photo, HistoryItem *item); void showPhoto(PhotoData *photo, PeerData *item); @@ -204,7 +200,7 @@ public: TempDirState localStorageState(); void tempDirDelete(int task); - void notifySettingGot(); + void notifySettingGot(); void notifySchedule(History *history, HistoryItem *item); void notifyClear(History *history = 0); void notifyClearFast(); @@ -215,7 +211,7 @@ public: void notifyUpdateAll(); void notifyActivateAll(); - QImage iconLarge() const; + QImage iconLarge() const; void sendPaths(); @@ -257,7 +253,7 @@ public slots: void showSettings(); void layerHidden(); void setInnerFocus(); - void updateTitleStatus(); + void updateConnectingStatus(); void quitFromTray(); void showFromTray(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); @@ -294,11 +290,13 @@ signals: void imageLoaded(); -private slots: + private slots: void onStateChanged(Qt::WindowState state); void onSettingsDestroyed(QObject *was); private: + void showConnecting(const QString &text, const QString &reconnect = QString()); + void hideConnecting(); QPixmap grabInner(); @@ -322,7 +320,7 @@ private: QTimer _isActiveTimer; bool _isActive = false; - ConnectingWidget *_connecting = nullptr; + ChildWidget _connecting = { nullptr }; Local::ClearManager *_clearManager = nullptr; diff --git a/Telegram/SourceFiles/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp index 8a3854e08d..16a7362be6 100644 --- a/Telegram/SourceFiles/media/media_audio.cpp +++ b/Telegram/SourceFiles/media/media_audio.cpp @@ -308,6 +308,7 @@ _loader(new AudioPlayerLoaders(&_loaderThread)) { connect(_fader, SIGNAL(audioStopped(const AudioMsgId&)), this, SLOT(onStopped(const AudioMsgId&))); connect(_fader, SIGNAL(error(const AudioMsgId&)), this, SLOT(onError(const AudioMsgId&))); connect(this, SIGNAL(stoppedOnError(const AudioMsgId&)), this, SIGNAL(updated(const AudioMsgId&)), Qt::QueuedConnection); + connect(this, SIGNAL(updated(const AudioMsgId&)), this, SLOT(onUpdated(const AudioMsgId&))); _loaderThread.start(); _faderThread.start(); } @@ -344,6 +345,13 @@ AudioPlayer::~AudioPlayer() { _loaderThread.wait(); } +void AudioPlayer::onUpdated(const AudioMsgId &audio) { + if (audio.type() == AudioMsgId::Type::Video) { + videoSoundProgress(audio); + } + notify(AudioMsgId(audio)); +} + void AudioPlayer::onError(const AudioMsgId &audio) { emit stoppedOnError(audio); if (audio.type() == AudioMsgId::Type::Voice) { @@ -906,24 +914,16 @@ bool audioCheckError() { } // namespace internal AudioCapture::AudioCapture() : _capture(new AudioCaptureInner(&_captureThread)) { - connect(this, SIGNAL(captureOnStart()), _capture, SLOT(onStart())); - connect(this, SIGNAL(captureOnStop(bool)), _capture, SLOT(onStop(bool))); - connect(_capture, SIGNAL(done(QByteArray,VoiceWaveform,qint32)), this, SIGNAL(onDone(QByteArray,VoiceWaveform,qint32))); - connect(_capture, SIGNAL(update(quint16,qint32)), this, SIGNAL(onUpdate(quint16,qint32))); - connect(_capture, SIGNAL(error()), this, SIGNAL(onError())); + connect(this, SIGNAL(start()), _capture, SLOT(onStart())); + connect(this, SIGNAL(stop(bool)), _capture, SLOT(onStop(bool))); + connect(_capture, SIGNAL(done(QByteArray,VoiceWaveform,qint32)), this, SIGNAL(done(QByteArray,VoiceWaveform,qint32))); + connect(_capture, SIGNAL(updated(quint16,qint32)), this, SIGNAL(updated(quint16,qint32))); + connect(_capture, SIGNAL(error()), this, SIGNAL(error())); connect(&_captureThread, SIGNAL(started()), _capture, SLOT(onInit())); connect(&_captureThread, SIGNAL(finished()), _capture, SLOT(deleteLater())); _captureThread.start(); } -void AudioCapture::start() { - emit captureOnStart(); -} - -void AudioCapture::stop(bool needResult) { - emit captureOnStop(needResult); -} - bool AudioCapture::check() { if (auto defaultDevice = alcGetString(0, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) { if (auto device = alcCaptureOpenDevice(defaultDevice, AudioVoiceMsgFrequency, AL_FORMAT_MONO16, AudioVoiceMsgFrequency / 5)) { @@ -1664,7 +1664,7 @@ void AudioCaptureInner::onTimeout() { } qint32 samplesFull = d->fullSamples + _captured.size() / sizeof(short), samplesSinceUpdate = samplesFull - d->lastUpdate; if (samplesSinceUpdate > AudioVoiceMsgUpdateView * AudioVoiceMsgFrequency / 1000) { - emit update(d->levelMax, samplesFull); + emit updated(d->levelMax, samplesFull); d->lastUpdate = samplesFull; d->levelMax = 0; } diff --git a/Telegram/SourceFiles/media/media_audio.h b/Telegram/SourceFiles/media/media_audio.h index 87b8cfd081..a0e767b91c 100644 --- a/Telegram/SourceFiles/media/media_audio.h +++ b/Telegram/SourceFiles/media/media_audio.h @@ -55,7 +55,7 @@ struct AudioPlaybackState { int32 frequency = 0; }; -class AudioPlayer : public QObject { +class AudioPlayer : public QObject, public base::Observable { Q_OBJECT public: @@ -70,7 +70,6 @@ public: void initFromVideo(uint64 videoPlayId, std_::unique_ptr &&data, int64 position); void feedFromVideo(VideoSoundPart &&part); int64 getVideoCorrectedTime(uint64 playId, int64 frameMs, uint64 systemMs); - void videoSoundProgress(const AudioMsgId &audio); AudioPlaybackState currentVideoState(uint64 videoPlayId); void stopFromVideo(uint64 videoPlayId); void pauseFromVideo(uint64 videoPlayId); @@ -86,10 +85,12 @@ public: ~AudioPlayer(); -public slots: +private slots: void onError(const AudioMsgId &audio); void onStopped(const AudioMsgId &audio); + void onUpdated(const AudioMsgId &audio); + signals: void updated(const AudioMsgId &audio); void stoppedOnError(const AudioMsgId &audio); @@ -110,6 +111,8 @@ private: bool updateCurrentStarted(AudioMsgId::Type type, int32 pos = -1); bool checkCurrentALError(AudioMsgId::Type type); + void videoSoundProgress(const AudioMsgId &audio); + struct AudioMsg { void clear(); @@ -185,27 +188,21 @@ class AudioCapture : public QObject { Q_OBJECT public: - AudioCapture(); - void start(); - void stop(bool needResult); - bool check(); ~AudioCapture(); signals: + void start(); + void stop(bool needResult); - void captureOnStart(); - void captureOnStop(bool needResult); - - void onDone(QByteArray data, VoiceWaveform waveform, qint32 samples); - void onUpdate(quint16 level, qint32 samples); - void onError(); + void done(QByteArray data, VoiceWaveform waveform, qint32 samples); + void updated(quint16 level, qint32 samples); + void error(); private: - friend class AudioCaptureInner; QThread _captureThread; @@ -270,18 +267,15 @@ class AudioCaptureInner : public QObject { Q_OBJECT public: - AudioCaptureInner(QThread *thread); ~AudioCaptureInner(); signals: - void error(); - void update(quint16 level, qint32 samples); + void updated(quint16 level, qint32 samples); void done(QByteArray data, VoiceWaveform waveform, qint32 samples); - public slots: - +public slots: void onInit(); void onStart(); void onStop(bool needResult); @@ -289,7 +283,6 @@ signals: void onTimeout(); private: - void processFrame(int32 offset, int32 framesize); void writeFrame(AVFrame *frame); diff --git a/Telegram/SourceFiles/mtproto/facade.cpp b/Telegram/SourceFiles/mtproto/facade.cpp index a5293f3535..43498d474b 100644 --- a/Telegram/SourceFiles/mtproto/facade.cpp +++ b/Telegram/SourceFiles/mtproto/facade.cpp @@ -851,7 +851,7 @@ void finish() { _started = false; } -void authed(int32 uid) { +void setAuthedId(int32 uid) { internal::authed(uid); } diff --git a/Telegram/SourceFiles/mtproto/facade.h b/Telegram/SourceFiles/mtproto/facade.h index 6634fb8126..15741c44cb 100644 --- a/Telegram/SourceFiles/mtproto/facade.h +++ b/Telegram/SourceFiles/mtproto/facade.h @@ -180,7 +180,7 @@ int32 state(mtpRequestId req); // < 0 means waiting for such count of ms void finish(); -void authed(int32 uid); +void setAuthedId(int32 uid); int32 authedId(); void logoutKeys(RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail); diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.cpp b/Telegram/SourceFiles/settings/settings_scale_widget.cpp index 7660e50502..4f4f714d13 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_scale_widget.cpp @@ -217,7 +217,7 @@ void ScaleWidget::setScale(DBIScale newScale) { cSetConfigScale(newScale); Local::writeSettings(); - App::wnd()->getTitle()->showUpdateBtn(); + App::wnd()->getTitle()->updateControlsVisibility(); if (newScale == dbisAuto && !_auto->checked()) { _auto->setChecked(true); } else if (newScale != dbisAuto && _auto->checked()) { diff --git a/Telegram/SourceFiles/sysbuttons.cpp b/Telegram/SourceFiles/sysbuttons.cpp index 0614cf322b..7b429cb867 100644 --- a/Telegram/SourceFiles/sysbuttons.cpp +++ b/Telegram/SourceFiles/sysbuttons.cpp @@ -35,7 +35,6 @@ SysBtn::SysBtn(QWidget *parent, const style::sysButton &st, const QString &text) int32 w = _st.size.width() + (_text.isEmpty() ? 0 : ((_st.size.width() - _st.img.pxWidth()) / 2 + st::titleTextButton.font->width(_text))); resize(w, _st.size.height()); setCursor(style::cur_default); - connect(this, SIGNAL(stateChanged(int, ButtonStateChangeSource)), this, SLOT(onStateChange(int, ButtonStateChangeSource))); } void SysBtn::setText(const QString &text) { @@ -49,7 +48,7 @@ void SysBtn::setOverLevel(float64 level) { update(); } -void SysBtn::onStateChange(int oldState, ButtonStateChangeSource source) { +void SysBtn::onStateChanged(int oldState, ButtonStateChangeSource source) { a_color.start((_state & StateOver ? _st.overColor : _st.color)->c); if (source == ButtonByUser || source == ButtonByPress) { @@ -109,60 +108,48 @@ void SysBtn::step_color(float64 ms, bool timer) { if (timer) update(); } -MinimizeBtn::MinimizeBtn(QWidget *parent, MainWindow *window) : SysBtn(parent, st::sysMin), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); +MinimizeBtn::MinimizeBtn(QWidget *parent) : SysBtn(parent, st::sysMin) { + setClickedCallback([this]() { + window()->setWindowState(Qt::WindowMinimized); + }); } -void MinimizeBtn::onClick() { - wnd->setWindowState(Qt::WindowMinimized); +MaximizeBtn::MaximizeBtn(QWidget *parent) : SysBtn(parent, st::sysMax) { + setClickedCallback([this]() { + window()->setWindowState(Qt::WindowMaximized); + }); } -MaximizeBtn::MaximizeBtn(QWidget *parent, MainWindow *window) : SysBtn(parent, st::sysMax), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); +RestoreBtn::RestoreBtn(QWidget *parent) : SysBtn(parent, st::sysRes) { + setClickedCallback([this]() { + window()->setWindowState(Qt::WindowNoState); + }); } -void MaximizeBtn::onClick() { - wnd->setWindowState(Qt::WindowMaximized); +CloseBtn::CloseBtn(QWidget *parent) : SysBtn(parent, st::sysCls) { + setClickedCallback([this]() { + window()->close(); + }); } -RestoreBtn::RestoreBtn(QWidget *parent, MainWindow *window) : SysBtn(parent, st::sysRes), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); -} - -void RestoreBtn::onClick() { - wnd->setWindowState(Qt::WindowNoState); -} - -CloseBtn::CloseBtn(QWidget *parent, MainWindow *window) : SysBtn(parent, st::sysCls), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); -} - -void CloseBtn::onClick() { - wnd->close(); -} - -UpdateBtn::UpdateBtn(QWidget *parent, MainWindow *window, const QString &text) : SysBtn(parent, st::sysUpd, text), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); -} - -void UpdateBtn::onClick() { +UpdateBtn::UpdateBtn(QWidget *parent) : SysBtn(parent, st::sysUpd, lang(lng_menu_update)) { + setClickedCallback([]() { #ifndef TDESKTOP_DISABLE_AUTOUPDATE - checkReadyUpdate(); - if (Sandbox::updatingState() == Application::UpdatingReady) { - cSetRestartingUpdate(true); - } else + checkReadyUpdate(); + if (Sandbox::updatingState() == Application::UpdatingReady) { + cSetRestartingUpdate(true); + } else #endif - { - cSetRestarting(true); - cSetRestartingToSettings(false); - } - App::quit(); + { + cSetRestarting(true); + cSetRestartingToSettings(false); + } + App::quit(); + }); } -LockBtn::LockBtn(QWidget *parent, MainWindow *window) : SysBtn(parent, st::sysLock), wnd(window) { - connect(this, SIGNAL(clicked()), this, SLOT(onClick())); -} - -void LockBtn::onClick() { - Shortcuts::launch(qsl("lock_telegram")); +LockBtn::LockBtn(QWidget *parent) : SysBtn(parent, st::sysLock) { + setClickedCallback([] { + Shortcuts::launch(qsl("lock_telegram")); + }); } diff --git a/Telegram/SourceFiles/sysbuttons.h b/Telegram/SourceFiles/sysbuttons.h index 88ff7b0a1e..537c17b181 100644 --- a/Telegram/SourceFiles/sysbuttons.h +++ b/Telegram/SourceFiles/sysbuttons.h @@ -23,13 +23,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/animation.h" #include "ui/button.h" -class MainWindow; - class SysBtn : public Button { - Q_OBJECT - public: - SysBtn(QWidget *parent, const style::sysButton &st, const QString &text = QString()); void setText(const QString &text); @@ -42,11 +37,8 @@ public: void step_color(float64 ms, bool timer); -public slots: - - void onStateChange(int oldState, ButtonStateChangeSource source); - protected: + void onStateChanged(int oldState, ButtonStateChangeSource source) override; style::sysButton _st; anim::cvalue a_color; @@ -58,97 +50,37 @@ protected: }; class MinimizeBtn : public SysBtn { - Q_OBJECT - public: + MinimizeBtn(QWidget *parent); - MinimizeBtn(QWidget *parent, MainWindow *window); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; class MaximizeBtn : public SysBtn { - Q_OBJECT - public: + MaximizeBtn(QWidget *parent); - MaximizeBtn(QWidget *parent, MainWindow *window); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; class RestoreBtn : public SysBtn { - Q_OBJECT - public: + RestoreBtn(QWidget *parent); - RestoreBtn(QWidget *parent, MainWindow *window); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; class CloseBtn : public SysBtn { - Q_OBJECT - public: + CloseBtn(QWidget *parent); - CloseBtn(QWidget *parent, MainWindow *window); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; class UpdateBtn : public SysBtn { - Q_OBJECT - public: + UpdateBtn(QWidget *parent); - UpdateBtn(QWidget *parent, MainWindow *window, const QString &text = QString()); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; class LockBtn : public SysBtn { - Q_OBJECT - public: + LockBtn(QWidget *parent); - LockBtn(QWidget *parent, MainWindow *window); - -public slots: - - void onClick(); - -private: - - MainWindow *wnd; }; diff --git a/Telegram/SourceFiles/title.cpp b/Telegram/SourceFiles/title.cpp index 05adda84b3..3c370c0111 100644 --- a/Telegram/SourceFiles/title.cpp +++ b/Telegram/SourceFiles/title.cpp @@ -27,71 +27,86 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "application.h" #include "boxes/contactsbox.h" #include "boxes/aboutbox.h" +#include "media/media_audio.h" #include "media/player/media_player_button.h" -TitleHider::TitleHider(QWidget *parent) : QWidget(parent), _level(0) { +class TitleWidget::Hider : public TWidget { +public: + Hider(QWidget *parent); + + using ClickedCallback = base::lambda_unique; + void setClickedCallback(ClickedCallback &&callback) { + _callback = std_::move(callback); + } + void setLevel(float64 level); + +protected: + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + +private: + ClickedCallback _callback; + float64 _level = 0; + +}; + +TitleWidget::Hider::Hider(QWidget *parent) : TWidget(parent) { } -void TitleHider::paintEvent(QPaintEvent *e) { +void TitleWidget::Hider::paintEvent(QPaintEvent *e) { QPainter p(this); p.setOpacity(_level * st::layerAlpha); p.fillRect(App::main()->dlgsWidth(), 0, width() - App::main()->dlgsWidth(), height(), st::layerBg->b); } -void TitleHider::mousePressEvent(QMouseEvent *e) { - if (e->button() == Qt::LeftButton) { - emit static_cast(parentWidget())->hiderClicked(); +void TitleWidget::Hider::mousePressEvent(QMouseEvent *e) { + if (e->button() == Qt::LeftButton && _callback) { + _callback(); } } -void TitleHider::setLevel(float64 level) { +void TitleWidget::Hider::setLevel(float64 level) { _level = level; update(); } -TitleWidget::TitleWidget(MainWindow *window) : TWidget(window) -, wnd(window) -, hideLevel(0) -, hider(0) +TitleWidget::TitleWidget(QWidget *parent) : TWidget(parent) , _cancel(this, lang(lng_cancel), st::titleTextButton) , _settings(this, lang(lng_menu_settings), st::titleTextButton) , _contacts(this, lang(lng_menu_contacts), st::titleTextButton) , _about(this, lang(lng_menu_about), st::titleTextButton) -, _player(this) -, _lock(this, window) -, _update(this, window, lang(lng_menu_update)) -, _minimize(this, window) -, _maximize(this, window) -, _restore(this, window) -, _close(this, window) +, _lock(this) +, _update(this) +, _minimize(this) +, _maximize(this) +, _restore(this) +, _close(this) , _a_update(animation(this, &TitleWidget::step_update)) -, lastMaximized(!(window->windowState() & Qt::WindowMaximized)) { - setGeometry(0, 0, wnd->width(), st::titleHeight); +, lastMaximized(!(parent->windowState() & Qt::WindowMaximized)) { + setGeometry(0, 0, parent->width(), st::titleHeight); setAttribute(Qt::WA_OpaquePaintEvent); - _lock.hide(); - _update.hide(); - _cancel.hide(); - if ( -#ifndef TDESKTOP_DISABLE_AUTOUPDATE - Sandbox::updatingState() == Application::UpdatingReady || -#endif - Global::LocalPasscode() - ) { - showUpdateBtn(); - } + onWindowStateChanged(); + updateControlsVisibility(); connect(&_cancel, SIGNAL(clicked()), this, SIGNAL(hiderClicked())); - connect(&_settings, SIGNAL(clicked()), window, SLOT(showSettings())); + connect(&_settings, SIGNAL(clicked()), parent, SLOT(showSettings())); connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts())); connect(&_about, SIGNAL(clicked()), this, SLOT(onAbout())); - connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onWindowStateChanged(Qt::WindowState))); + connect(parent->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(onWindowStateChanged(Qt::WindowState))); #ifndef TDESKTOP_DISABLE_AUTOUPDATE - Sandbox::connect(SIGNAL(updateReady()), this, SLOT(showUpdateBtn())); + Sandbox::connect(SIGNAL(updateReady()), this, SLOT(updateControlsVisibility())); #endif subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); }); + if (auto player = audioPlayer()) { + subscribe(player, [this](const AudioMsgId &audio) { + if (audio.type() == AudioMsgId::Type::Song) { + handleSongUpdate(audio); + } + }); + } if (cPlatform() != dbipWindows) { _minimize.hide(); @@ -127,20 +142,31 @@ void TitleWidget::setHideLevel(float64 level) { if (level != hideLevel) { hideLevel = level; if (hideLevel) { - if (!hider) { - hider = new TitleHider(this); - hider->move(0, 0); - hider->resize(size()); - if (Adaptive::OneColumn()) { - hider->hide(); - } else { - hider->show(); - } + if (!_hider) { + _hider.create(this); + _hider->setGeometry(rect()); + _hider->setClickedCallback([this]() { emit hiderClicked(); }); + _hider->setVisible(!Adaptive::OneColumn()); } - hider->setLevel(hideLevel); + _hider->setLevel(hideLevel); } else { - if (hider) hider->deleteLater(); - hider = 0; + if (_hider) { + _hider.destroyDelayed(); + } + } + } +} + +void TitleWidget::handleSongUpdate(const AudioMsgId &audioId) { + t_assert(audioId.type() == AudioMsgId::Type::Song); + + AudioMsgId playing; + auto playbackState = audioPlayer()->currentState(&playing, audioId.type()); + if (playing == audioId) { + auto songIsPlaying = !(playbackState.state & AudioPlayerStoppedMask) && (playbackState.state != AudioPlayerFinishing); + if (songIsPlaying && !_player) { + _player.create(this); + updateControlsVisibility(); } } } @@ -157,12 +183,7 @@ void TitleWidget::onAbout() { Ui::showLayer(new AboutBox()); } -TitleWidget::~TitleWidget() { - delete hider; - hider = 0; -} - -void TitleWidget::resizeEvent(QResizeEvent *e) { +void TitleWidget::updateControlsPosition() { QPoint p(width() - ((cPlatform() == dbipWindows && lastMaximized) ? 0 : st::sysBtnDelta), 0); if (!_update.isHidden()) { @@ -177,16 +198,16 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { } _cancel.move(p.x() - _cancel.width(), 0); - if (cPlatform() == dbipWindows) { - p.setX(p.x() - _close.width()); - _close.move(p); + if (cPlatform() == dbipWindows) { + p.setX(p.x() - _close.width()); + _close.move(p); - p.setX(p.x() - _maximize.width()); - _restore.move(p); _maximize.move(p); + p.setX(p.x() - _maximize.width()); + _restore.move(p); _maximize.move(p); - p.setX(p.x() - _minimize.width()); - _minimize.move(p); - } + p.setX(p.x() - _minimize.width()); + _minimize.move(p); + } if (_update.isHidden() && !_lock.isHidden()) { p.setX(p.x() - _lock.width()); _lock.move(p); @@ -197,61 +218,108 @@ void TitleWidget::resizeEvent(QResizeEvent *e) { } _settings.move(st::titleMenuOffset, 0); - if (MTP::authedId() && _cancel.isHidden() && !App::passcoded()) { - if (_contacts.isHidden()) _contacts.show(); + if (_contacts.isHidden()) { + _about.move(_settings.x() + _settings.width(), 0); + } else { _contacts.move(_settings.x() + _settings.width(), 0); _about.move(_contacts.x() + _contacts.width(), 0); - } else { - if (!_contacts.isHidden()) _contacts.hide(); - if (!MTP::authedId()) _about.move(_settings.x() + _settings.width(), 0); } - if (hider) hider->resize(size()); + if (_hider) { + _hider->resize(size()); + } } -void TitleWidget::updateBackButton() { - if (App::passcoded()) { - if (!_cancel.isHidden()) _cancel.hide(); - if (!_settings.isHidden()) _settings.hide(); - if (!_contacts.isHidden()) _contacts.hide(); - if (!_about.isHidden()) _about.hide(); - _lock.setSysBtnStyle(st::sysUnlock); - } else { - _lock.setSysBtnStyle(st::sysLock); - if (Adaptive::OneColumn() && App::main() && App::main()->selectingPeer()) { - _cancel.show(); - if (!_settings.isHidden()) _settings.hide(); - if (!_contacts.isHidden()) _contacts.hide(); - if (!_about.isHidden()) _about.hide(); - } else { - if (!_cancel.isHidden()) _cancel.hide(); - bool authed = (MTP::authedId() > 0); - if (Adaptive::OneColumn()) { - if (_settings.isHidden()) _settings.show(); - if (authed && _contacts.isHidden()) _contacts.show(); - if (_about.isHidden()) _about.show(); - } else { - if (_settings.isHidden()) _settings.show(); - if (authed && _contacts.isHidden()) _contacts.show(); - if (_about.isHidden()) _about.show(); - } - } - } - showUpdateBtn(); +void TitleWidget::resizeEvent(QResizeEvent *e) { + updateControlsPosition(); +} + +void TitleWidget::updateControlsVisibility() { + auto passcoded = App::passcoded(); + auto authed = (App::main() != nullptr); + auto selecting = authed && App::main()->selectingPeer(); + auto oneColumnSelecting = (Adaptive::OneColumn() && selecting && !passcoded); + + _cancel.setVisible(oneColumnSelecting); + + updateRestartButtonVisibility(); + updateMenuButtonsVisibility(); + updateSystemButtonsVisibility(); + + updateControlsPosition(); update(); } +void TitleWidget::updateRestartButtonVisibility() { +#ifndef TDESKTOP_DISABLE_AUTOUPDATE + bool updateReady = (Sandbox::updatingState() == Application::UpdatingReady); +#else + bool updateReady = false; +#endif + auto scaleRestarting = cEvalScale(cConfigScale()) != cEvalScale(cRealScale()); + + auto updateVisible = _cancel.isHidden() && (updateReady || scaleRestarting); + if (updateVisible) { + _update.setText(lang(updateReady ? lng_menu_update : lng_menu_restart)); + _update.show(); + _a_update.start(); + } else { + _update.hide(); + _a_update.stop(); + } +} + +void TitleWidget::updateMenuButtonsVisibility() { + if (_cancel.isHidden()) { + if (App::passcoded()) { + _settings.hide(); + _contacts.hide(); + _about.hide(); + _lock.setSysBtnStyle(st::sysUnlock); + } else { + _lock.setSysBtnStyle(st::sysLock); + _settings.show(); + _contacts.setVisible(App::main() != nullptr); + _about.show(); + } + } else { + _settings.hide(); + _contacts.hide(); + _about.hide(); + } +} + +void TitleWidget::updateSystemButtonsVisibility() { + if (_cancel.isHidden()) { + _lock.setVisible(Global::LocalPasscode()); + if (_player) { + _player->show(); + } + } else { + _lock.hide(); + if (_player) { + _player->hide(); + } + } + if (_update.isHidden() && _cancel.isHidden() && cPlatform() == dbipWindows) { + _minimize.show(); + maximizedChanged(lastMaximized, true); + _close.show(); + } else { + _minimize.hide(); + _restore.hide(); + _maximize.hide(); + _close.hide(); + } +} + void TitleWidget::updateAdaptiveLayout() { - updateBackButton(); + updateControlsVisibility(); if (Adaptive::OneColumn()) { updateCounter(); } - if (hider) { - if (Adaptive::OneColumn()) { - hider->hide(); - } else { - hider->show(); - } + if (_hider) { + _hider->setVisible(!Adaptive::OneColumn()); } } @@ -282,20 +350,24 @@ void TitleWidget::updateCounter() { } void TitleWidget::mousePressEvent(QMouseEvent *e) { - if (wnd->psHandleTitle()) return; - if (e->buttons() & Qt::LeftButton) { - wnd->wStartDrag(e); - e->accept(); + if (auto wnd = App::wnd()) { + if (wnd->psHandleTitle()) return; + if (e->buttons() & Qt::LeftButton) { + wnd->wStartDrag(e); + e->accept(); + } } } void TitleWidget::mouseDoubleClickEvent(QMouseEvent *e) { - if (wnd->psHandleTitle()) return; - Qt::WindowStates s(wnd->windowState()); - if (s.testFlag(Qt::WindowMaximized)) { - wnd->setWindowState(s & ~Qt::WindowMaximized); - } else { - wnd->setWindowState(s | Qt::WindowMaximized); + if (auto wnd = App::wnd()) { + if (wnd->psHandleTitle()) return; + Qt::WindowStates s(wnd->windowState()); + if (s.testFlag(Qt::WindowMaximized)) { + wnd->setWindowState(s & ~Qt::WindowMaximized); + } else { + wnd->setWindowState(s | Qt::WindowMaximized); + } } } @@ -304,49 +376,6 @@ void TitleWidget::onWindowStateChanged(Qt::WindowState state) { maximizedChanged(state == Qt::WindowMaximized); } -void TitleWidget::showUpdateBtn() { - if (Adaptive::OneColumn() && App::main() && App::main()->selectingPeer()) { - _cancel.show(); - _lock.hide(); - _update.hide(); - _minimize.hide(); - _restore.hide(); - _maximize.hide(); - _close.hide(); - return; - } - if (Global::LocalPasscode()) { - _lock.show(); - } else { - _lock.hide(); - } -#ifndef TDESKTOP_DISABLE_AUTOUPDATE - bool updateReady = (Sandbox::updatingState() == Application::UpdatingReady); -#else - bool updateReady = false; -#endif - if (updateReady || cEvalScale(cConfigScale()) != cEvalScale(cRealScale())) { - _update.setText(lang(updateReady ? lng_menu_update : lng_menu_restart)); - _update.show(); - resizeEvent(0); - _minimize.hide(); - _restore.hide(); - _maximize.hide(); - _close.hide(); - _a_update.start(); - } else { - _update.hide(); - if (cPlatform() == dbipWindows) { - _minimize.show(); - maximizedChanged(lastMaximized, true); - _close.show(); - } - _a_update.stop(); - } - resizeEvent(0); - update(); -} - void TitleWidget::maximizedChanged(bool maximized, bool force) { if (lastMaximized == maximized && !force) return; @@ -362,14 +391,14 @@ void TitleWidget::maximizedChanged(bool maximized, bool force) { _maximize.setVisible(!maximized); _restore.setVisible(maximized); - resizeEvent(0); + updateControlsPosition(); } HitTestType TitleWidget::hitTest(const QPoint &p) { if (App::wnd() && Ui::isLayerShown()) return HitTestNone; int x(p.x()), y(p.y()), w(width()), h(height()); - if (!Adaptive::OneColumn() && hider && x >= App::main()->dlgsWidth()) return HitTestNone; + if (!Adaptive::OneColumn() && _hider && x >= App::main()->dlgsWidth()) return HitTestNone; if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconImg.pxWidth() && y < st::titleIconPos.y() + st::titleIconImg.pxHeight()) { return HitTestIcon; diff --git a/Telegram/SourceFiles/title.h b/Telegram/SourceFiles/title.h index cb98ca3351..137daad830 100644 --- a/Telegram/SourceFiles/title.h +++ b/Telegram/SourceFiles/title.h @@ -29,31 +29,14 @@ namespace Player { class TitleButton; } // namespace Player } // namespace Media - -class TitleHider : public QWidget { -public: - - TitleHider(QWidget *parent); - void paintEvent(QPaintEvent *e); - void mousePressEvent(QMouseEvent *e); - void setLevel(float64 level); - -private: - - float64 _level; - -}; +class AudioMsgId; class TitleWidget : public TWidget, private base::Subscriber { Q_OBJECT public: + TitleWidget(QWidget *parent); - TitleWidget(MainWindow *parent); - void paintEvent(QPaintEvent *e); - void resizeEvent(QResizeEvent *e); - - void updateBackButton(); void updateCounter(); void mousePressEvent(QMouseEvent *e); @@ -71,28 +54,33 @@ public: void step_update(float64 ms, bool timer); - ~TitleWidget(); - public slots: - void onWindowStateChanged(Qt::WindowState state = Qt::WindowNoState); - void showUpdateBtn(); + void updateControlsVisibility(); void onContacts(); void onAbout(); signals: - void hiderClicked(); +protected: + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + private: void updateAdaptiveLayout(); + void updateRestartButtonVisibility(); + void updateMenuButtonsVisibility(); + void updateSystemButtonsVisibility(); + void updateControlsPosition(); - MainWindow *wnd; + void handleSongUpdate(const AudioMsgId &audioId); style::color statusColor; - float64 hideLevel; - TitleHider *hider; + class Hider; + float64 hideLevel = 0; + ChildWidget _hider = { nullptr }; float64 _lastUpdateMs; diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h index b12c4da1b3..31ae6d2f40 100644 --- a/Telegram/SourceFiles/ui/twidget.h +++ b/Telegram/SourceFiles/ui/twidget.h @@ -350,6 +350,12 @@ public: return ptr(); } + // Use that instead "= new T(parent, ...)" + template + void create(Parent &&parent, Args&&... args) { + delete _widget; + _widget = new T(std_::forward(parent), std_::forward(args)...); + } void destroy() { if (_widget) { delete _widget;