Title controls reordering done right. Title song play button created.

This commit is contained in:
John Preston 2016-09-21 14:44:20 +03:00
parent 5c20ae0411
commit a8f3582cb1
17 changed files with 320 additions and 407 deletions

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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:

View File

@ -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<MTPInputUser>(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() {

View File

@ -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<ConnectingWidget> _connecting = { nullptr };
Local::ClearManager *_clearManager = nullptr;

View File

@ -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;
}

View File

@ -55,7 +55,7 @@ struct AudioPlaybackState {
int32 frequency = 0;
};
class AudioPlayer : public QObject {
class AudioPlayer : public QObject, public base::Observable<AudioMsgId> {
Q_OBJECT
public:
@ -70,7 +70,6 @@ public:
void initFromVideo(uint64 videoPlayId, std_::unique_ptr<VideoSoundData> &&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);

View File

@ -851,7 +851,7 @@ void finish() {
_started = false;
}
void authed(int32 uid) {
void setAuthedId(int32 uid) {
internal::authed(uid);
}

View File

@ -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);

View File

@ -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()) {

View File

@ -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"));
});
}

View File

@ -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;
};

View File

@ -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()>;
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<TitleWidget*>(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;

View File

@ -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> _hider = { nullptr };
float64 _lastUpdateMs;

View File

@ -350,6 +350,12 @@ public:
return ptr();
}
// Use that instead "= new T(parent, ...)"
template <typename Parent, typename... Args>
void create(Parent &&parent, Args&&... args) {
delete _widget;
_widget = new T(std_::forward<Parent>(parent), std_::forward<Args>(args)...);
}
void destroy() {
if (_widget) {
delete _widget;