Hide floating player if video message is visible.

This commit is contained in:
John Preston 2017-05-23 17:04:59 +03:00
parent b7550f63c9
commit c58a48276f
9 changed files with 77 additions and 32 deletions

View File

@ -662,16 +662,10 @@ void HistoryWidget::scrollToCurrentVoiceMessage(FullMsgId fromId, FullMsgId toId
// And the scrollTop will be reset back to scrollTopItem + scrollTopOffset. // And the scrollTop will be reset back to scrollTopItem + scrollTopOffset.
notify_handlePendingHistoryUpdate(); notify_handlePendingHistoryUpdate();
auto fromTop = _list->itemTop(from);
auto toTop = _list->itemTop(to); auto toTop = _list->itemTop(to);
if (fromTop < 0 || toTop < 0) { if (toTop >= 0 && !isItemCompletelyHidden(from)) {
return; auto scrollTop = _scroll->scrollTop();
} auto scrollBottom = scrollTop + _scroll->height();
auto scrollTop = _scroll->scrollTop();
auto scrollBottom = scrollTop + _scroll->height();
auto fromBottom = fromTop + from->height();
if (fromTop < scrollBottom && fromBottom > scrollTop) {
auto toBottom = toTop + to->height(); auto toBottom = toTop + to->height();
if ((toTop < scrollTop && toBottom < scrollBottom) || (toTop > scrollTop && toBottom > scrollBottom)) { if ((toTop < scrollTop && toBottom < scrollBottom) || (toTop > scrollTop && toBottom > scrollBottom)) {
auto scrollTo = snap(itemTopForHighlight(to), 0, _scroll->scrollTopMax()); auto scrollTo = snap(itemTopForHighlight(to), 0, _scroll->scrollTopMax());
@ -2636,10 +2630,22 @@ void HistoryWidget::onScroll() {
} }
} }
bool HistoryWidget::isItemCompletelyHidden(HistoryItem *item) const {
auto top = _list->itemTop(item);
if (top < 0) {
return true;
}
auto bottom = top + item->height();
auto scrollTop = _scroll->scrollTop();
auto scrollBottom = scrollTop + _scroll->height();
return (top >= scrollBottom || bottom <= scrollTop);
}
void HistoryWidget::visibleAreaUpdated() { void HistoryWidget::visibleAreaUpdated() {
if (_list && !_scroll->isHidden()) { if (_list && !_scroll->isHidden()) {
int scrollTop = _scroll->scrollTop(); auto scrollTop = _scroll->scrollTop();
int scrollBottom = scrollTop + _scroll->height(); auto scrollBottom = scrollTop + _scroll->height();
_list->visibleAreaUpdated(scrollTop, scrollBottom); _list->visibleAreaUpdated(scrollTop, scrollBottom);
if (_history->loadedAtBottom() && (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0))) { if (_history->loadedAtBottom() && (_history->unreadCount() > 0 || (_migrated && _migrated->unreadCount() > 0))) {
auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr); auto showFrom = (_migrated && _migrated->showFrom) ? _migrated->showFrom : (_history ? _history->showFrom : nullptr);
@ -2647,6 +2653,7 @@ void HistoryWidget::visibleAreaUpdated() {
historyWasRead(ReadServerHistoryChecks::OnlyIfUnread); historyWasRead(ReadServerHistoryChecks::OnlyIfUnread);
} }
} }
controller()->floatPlayerAreaUpdated().notify(true);
} }
} }

View File

@ -180,6 +180,7 @@ public:
void dragLeaveEvent(QDragLeaveEvent *e) override; void dragLeaveEvent(QDragLeaveEvent *e) override;
void dropEvent(QDropEvent *e) override; void dropEvent(QDropEvent *e) override;
bool isItemCompletelyHidden(HistoryItem *item) const;
void updateTopBarSelection(); void updateTopBarSelection();
bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms); bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);

View File

@ -152,6 +152,9 @@ MainWidget::MainWidget(QWidget *parent, gsl::not_null<Window::Controller*> contr
subscribe(_controller->dialogsWidthRatio(), [this](float64) { subscribe(_controller->dialogsWidthRatio(), [this](float64) {
updateControlsGeometry(); updateControlsGeometry();
}); });
subscribe(_controller->floatPlayerAreaUpdated(), [this] {
checkFloatPlayerVisibility();
});
QCoreApplication::instance()->installEventFilter(this); QCoreApplication::instance()->installEventFilter(this);
@ -234,7 +237,7 @@ void MainWidget::checkCurrentFloatPlayer() {
auto state = Media::Player::instance()->current(AudioMsgId::Type::Voice); auto state = Media::Player::instance()->current(AudioMsgId::Type::Voice);
auto fullId = state.contextId(); auto fullId = state.contextId();
auto last = currentFloatPlayer(); auto last = currentFloatPlayer();
if (!last || last->widget->itemId() != fullId) { if (!last || last->widget->detached() || last->widget->item()->fullId() != fullId) {
if (last) { if (last) {
last->widget->detach(); last->widget->detach();
} }
@ -243,9 +246,10 @@ void MainWidget::checkCurrentFloatPlayer() {
if (auto document = media->getDocument()) { if (auto document = media->getDocument()) {
if (document->isRoundVideo()) { if (document->isRoundVideo()) {
_playerFloats.push_back(std::make_unique<Float>(this, item, [this](Float *instance, bool visible) { _playerFloats.push_back(std::make_unique<Float>(this, item, [this](Float *instance, bool visible) {
toggleFloatPlayer(instance, visible); instance->hiddenByWidget = !visible;
toggleFloatPlayer(instance);
})); }));
toggleFloatPlayer(currentFloatPlayer(), true); checkFloatPlayerVisibility();
} }
} }
} }
@ -253,8 +257,10 @@ void MainWidget::checkCurrentFloatPlayer() {
} }
} }
void MainWidget::toggleFloatPlayer(Float *instance, bool visible) { void MainWidget::toggleFloatPlayer(Float *instance) {
auto visible = !instance->hiddenByHistory && !instance->hiddenByWidget && !instance->widget->detached();
if (instance->visible != visible) { if (instance->visible != visible) {
instance->widget->resetMouseState();
instance->visible = visible; instance->visible = visible;
instance->visibleAnimation.start([this, instance] { instance->visibleAnimation.start([this, instance] {
updateFloatPlayerPosition(instance); updateFloatPlayerPosition(instance);
@ -263,6 +269,20 @@ void MainWidget::toggleFloatPlayer(Float *instance, bool visible) {
} }
} }
void MainWidget::checkFloatPlayerVisibility() {
auto instance = currentFloatPlayer();
if (!instance) {
return;
}
if (_history->isHidden() || _history->isItemCompletelyHidden(instance->widget->item())) {
instance->hiddenByHistory = false;
} else {
instance->hiddenByHistory = true;
}
toggleFloatPlayer(instance);
}
void MainWidget::updateFloatPlayerPosition(Float *instance) { void MainWidget::updateFloatPlayerPosition(Float *instance) {
auto visible = instance->visibleAnimation.current(instance->visible ? 1. : 0.); auto visible = instance->visibleAnimation.current(instance->visible ? 1. : 0.);
if (visible == 0. && !instance->visible) { if (visible == 0. && !instance->visible) {
@ -755,6 +775,7 @@ void MainWidget::noHider(HistoryHider *destroyed) {
} else { } else {
_history->showAnimated(Window::SlideDirection::FromRight, animationParams); _history->showAnimated(Window::SlideDirection::FromRight, animationParams);
} }
checkFloatPlayerVisibility();
} }
} else { } else {
if (_forwardConfirm) { if (_forwardConfirm) {
@ -796,6 +817,7 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
updateControlsGeometry(); updateControlsGeometry();
_dialogs->activate(); _dialogs->activate();
} }
checkFloatPlayerVisibility();
} }
void MainWidget::forwardLayer(int forwardSelected) { void MainWidget::forwardLayer(int forwardSelected) {
@ -2498,6 +2520,8 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
} }
_dialogs->update(); _dialogs->update();
} }
checkFloatPlayerVisibility();
} }
PeerData *MainWidget::ui_getPeerForMouseAction() { PeerData *MainWidget::ui_getPeerForMouseAction() {
@ -2625,6 +2649,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
_history->hide(); _history->hide();
if (Adaptive::OneColumn()) _dialogs->hide(); if (Adaptive::OneColumn()) _dialogs->hide();
checkFloatPlayerVisibility();
orderWidgets(); orderWidgets();
} }
@ -2784,6 +2809,7 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool
_wideSection->showFast(); _wideSection->showFast();
} }
checkFloatPlayerVisibility();
orderWidgets(); orderWidgets();
} }
@ -3128,6 +3154,9 @@ void MainWidget::hideAll() {
_player->hide(); _player->hide();
_playerHeight = 0; _playerHeight = 0;
} }
for (auto &instance : _playerFloats) {
instance->widget->hide();
}
} }
void MainWidget::showAll() { void MainWidget::showAll() {
@ -3199,6 +3228,12 @@ void MainWidget::showAll() {
_playerHeight = _player->contentHeight(); _playerHeight = _player->contentHeight();
} }
updateControlsGeometry(); updateControlsGeometry();
if (auto instance = currentFloatPlayer()) {
checkFloatPlayerVisibility();
if (instance->visible) {
instance->widget->show();
}
}
App::wnd()->checkHistoryActivation(); App::wnd()->checkHistoryActivation();
} }

View File

@ -466,6 +466,8 @@ private:
template <typename ToggleCallback> template <typename ToggleCallback>
Float(QWidget *parent, HistoryItem *item, ToggleCallback callback); Float(QWidget *parent, HistoryItem *item, ToggleCallback callback);
bool hiddenByWidget = false;
bool hiddenByHistory = false;
bool visible = false; bool visible = false;
Animation visibleAnimation; Animation visibleAnimation;
Window::Corner corner = Window::Corner::TopRight; Window::Corner corner = Window::Corner::TopRight;
@ -574,7 +576,8 @@ private:
void clearCachedBackground(); void clearCachedBackground();
void checkCurrentFloatPlayer(); void checkCurrentFloatPlayer();
void toggleFloatPlayer(Float *instance, bool visible); void toggleFloatPlayer(Float *instance);
void checkFloatPlayerVisibility();
void updateFloatPlayerPosition(Float *instance); void updateFloatPlayerPosition(Float *instance);
void removeFloatPlayer(Float *instance); void removeFloatPlayer(Float *instance);
Float *currentFloatPlayer() const { Float *currentFloatPlayer() const {

View File

@ -887,7 +887,6 @@ void Mixer::seek(AudioMsgId::Type type, int64 position) {
resetFadeStartPosition(type, position - current->bufferedPosition); resetFadeStartPosition(type, position - current->bufferedPosition);
} else { } else {
setStoppedState(current); setStoppedState(current);
if (streamCreated) alSourceStop(current->stream.source);
} }
switch (current->state.state) { switch (current->state.state) {
case State::Pausing: case State::Pausing:
@ -1009,6 +1008,10 @@ TrackState Mixer::currentState(AudioMsgId::Type type) {
void Mixer::setStoppedState(Track *current, State state) { void Mixer::setStoppedState(Track *current, State state) {
current->state.state = state; current->state.state = state;
current->state.position = 0; current->state.position = 0;
if (current->isStreamCreated()) {
alSourceStop(current->stream.source);
alSourcef(current->stream.source, AL_GAIN, 1);
}
} }
void Mixer::clearStoppedAtStart(const AudioMsgId &audio) { void Mixer::clearStoppedAtStart(const AudioMsgId &audio) {
@ -1209,18 +1212,14 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF
if (fading || playing) { if (fading || playing) {
fading = false; fading = false;
playing = false; playing = false;
if (track->isStreamCreated()) {
alSourceStop(track->stream.source);
alSourcef(track->stream.source, AL_GAIN, 1);
if (errorHappened()) return EmitError;
}
if (track->state.state == State::Pausing) { if (track->state.state == State::Pausing) {
track->state.state = State::PausedAtEnd; setStoppedState(track, State::PausedAtEnd);
} else if (track->state.state == State::Stopping) { } else if (track->state.state == State::Stopping) {
setStoppedState(track, State::Stopped); setStoppedState(track, State::Stopped);
} else { } else {
setStoppedState(track, State::StoppedAtEnd); setStoppedState(track, State::StoppedAtEnd);
} }
if (errorHappened()) return EmitError;
emitSignals |= EmitStopped; emitSignals |= EmitStopped;
} }
} else if (fading && state == AL_PLAYING) { } else if (fading && state == AL_PLAYING) {
@ -1232,9 +1231,6 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF
switch (track->state.state) { switch (track->state.state) {
case State::Stopping: { case State::Stopping: {
alSourceStop(track->stream.source);
if (errorHappened()) return EmitError;
setStoppedState(track); setStoppedState(track);
state = AL_STOPPED; state = AL_STOPPED;
} break; } break;
@ -1284,8 +1280,7 @@ int32 Fader::updateOnePlayback(Mixer::Track *track, bool &hasPlaying, bool &hasF
} }
void Fader::setStoppedState(Mixer::Track *track, State state) { void Fader::setStoppedState(Mixer::Track *track, State state) {
track->state.state = state; mixer()->setStoppedState(track, state);
track->state.position = 0;
} }
void Fader::onSuppressSong() { void Fader::onSuppressSong() {

View File

@ -231,6 +231,7 @@ private:
}; };
// Thread: Any. Must be locked: AudioMutex.
void setStoppedState(Track *current, State state = State::Stopped); void setStoppedState(Track *current, State state = State::Stopped);
Track *trackForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type) Track *trackForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type)

View File

@ -125,8 +125,7 @@ AudioMsgId Loaders::clear(AudioMsgId::Type type) {
} }
void Loaders::setStoppedState(Mixer::Track *track, State state) { void Loaders::setStoppedState(Mixer::Track *track, State state) {
track->state.state = state; mixer()->setStoppedState(track, state);
track->state.position = 0;
} }
void Loaders::emitError(AudioMsgId::Type type) { void Loaders::emitError(AudioMsgId::Type type) {

View File

@ -31,8 +31,8 @@ class Float : public TWidget, private base::Subscriber {
public: public:
Float(QWidget *parent, HistoryItem *item, base::lambda<void(bool visible)> toggleCallback); Float(QWidget *parent, HistoryItem *item, base::lambda<void(bool visible)> toggleCallback);
FullMsgId itemId() const { HistoryItem *item() const {
return _item ? _item->fullId() : FullMsgId(); return _item;
} }
void setOpacity(float64 opacity) { void setOpacity(float64 opacity) {
_opacity = opacity; _opacity = opacity;

View File

@ -65,6 +65,9 @@ public:
return _gifPauseLevelChanged; return _gifPauseLevelChanged;
} }
bool isGifPausedAtLeastFor(GifPauseReason reason) const; bool isGifPausedAtLeastFor(GifPauseReason reason) const;
base::Observable<void> &floatPlayerAreaUpdated() {
return _floatPlayerAreaUpdated;
}
struct ColumnLayout { struct ColumnLayout {
int bodyWidth; int bodyWidth;
@ -104,6 +107,7 @@ private:
GifPauseReasons _gifPauseReasons = { 0 }; GifPauseReasons _gifPauseReasons = { 0 };
base::Observable<void> _gifPauseLevelChanged; base::Observable<void> _gifPauseLevelChanged;
base::Observable<void> _floatPlayerAreaUpdated;
base::Variable<float64> _dialogsWidthRatio = { kDefaultDialogsWidthRatio }; base::Variable<float64> _dialogsWidthRatio = { kDefaultDialogsWidthRatio };
base::Variable<bool> _dialogsListFocused = { false }; base::Variable<bool> _dialogsListFocused = { false };