mirror of https://github.com/procxx/kepka.git
Add audio playlist using Info::Media::ListWidget.
This commit is contained in:
parent
63e89ddc9a
commit
5a7d8bcffb
|
@ -1148,12 +1148,12 @@ void HistoryDocument::initDimensions() {
|
||||||
|
|
||||||
if (thumbed) {
|
if (thumbed) {
|
||||||
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
||||||
if (!captioned && (_parent->Has<HistoryMessageSigned>() || _parent->Has<HistoryMessageEdited>())) {
|
|
||||||
_minh += st::msgDateFont->height - st::msgDateDelta.y();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
||||||
}
|
}
|
||||||
|
if (!captioned && (_parent->Has<HistoryMessageSigned>() || _parent->Has<HistoryMessageEdited>())) {
|
||||||
|
_minh += st::msgDateFont->height - st::msgDateDelta.y();
|
||||||
|
}
|
||||||
if (!isBubbleTop()) {
|
if (!isBubbleTop()) {
|
||||||
_minh -= st::msgFileTopMinus;
|
_minh -= st::msgFileTopMinus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ void ListController::restoreState(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
_controller->window()->showPeerHistory(
|
_controller->parentController()->showPeerHistory(
|
||||||
row->peer(),
|
row->peer(),
|
||||||
Window::SectionShow::Way::Forward);
|
Window::SectionShow::Way::Forward);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,16 +44,46 @@ not_null<PeerData*> CorrectPeer(PeerId peerId) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
rpl::producer<SparseIdsMergedSlice> AbstractController::mediaSource(
|
||||||
|
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||||
|
int limitBefore,
|
||||||
|
int limitAfter) const {
|
||||||
|
return SharedMediaMergedViewer(
|
||||||
|
SharedMediaMergedKey(
|
||||||
|
SparseIdsMergedSlice::Key(
|
||||||
|
peerId(),
|
||||||
|
migratedPeerId(),
|
||||||
|
aroundId),
|
||||||
|
section().mediaType()),
|
||||||
|
limitBefore,
|
||||||
|
limitAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<QString> AbstractController::mediaSourceQueryValue() const {
|
||||||
|
return rpl::single(QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractController::showSection(
|
||||||
|
Window::SectionMemento &&memento,
|
||||||
|
const Window::SectionShow ¶ms) {
|
||||||
|
return parentController()->showSection(std::move(memento), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractController::showBackFromStack(
|
||||||
|
const Window::SectionShow ¶ms) {
|
||||||
|
return parentController()->showBackFromStack(params);
|
||||||
|
}
|
||||||
|
|
||||||
Controller::Controller(
|
Controller::Controller(
|
||||||
not_null<WrapWidget*> widget,
|
not_null<WrapWidget*> widget,
|
||||||
not_null<Window::Controller*> window,
|
not_null<Window::Controller*> window,
|
||||||
not_null<ContentMemento*> memento)
|
not_null<ContentMemento*> memento)
|
||||||
: _widget(widget)
|
: AbstractController(window)
|
||||||
|
, _widget(widget)
|
||||||
, _peer(App::peer(memento->peerId()))
|
, _peer(App::peer(memento->peerId()))
|
||||||
, _migrated(memento->migratedPeerId()
|
, _migrated(memento->migratedPeerId()
|
||||||
? App::peer(memento->migratedPeerId())
|
? App::peer(memento->migratedPeerId())
|
||||||
: nullptr)
|
: nullptr)
|
||||||
, _window(window)
|
|
||||||
, _section(memento->section()) {
|
, _section(memento->section()) {
|
||||||
updateSearchControllers(memento);
|
updateSearchControllers(memento);
|
||||||
setupMigrationViewer();
|
setupMigrationViewer();
|
||||||
|
@ -66,11 +96,11 @@ void Controller::setupMigrationViewer() {
|
||||||
Notify::PeerUpdateValue(_peer, Notify::PeerUpdate::Flag::MigrationChanged)
|
Notify::PeerUpdateValue(_peer, Notify::PeerUpdate::Flag::MigrationChanged)
|
||||||
| rpl::start_with_next([this] {
|
| rpl::start_with_next([this] {
|
||||||
if (_peer->migrateTo() || (_peer->migrateFrom() != _migrated)) {
|
if (_peer->migrateTo() || (_peer->migrateFrom() != _migrated)) {
|
||||||
auto windowController = window();
|
auto window = parentController();
|
||||||
auto peerId = _peer->id;
|
auto peerId = _peer->id;
|
||||||
auto section = _section;
|
auto section = _section;
|
||||||
InvokeQueued(_widget, [=] {
|
InvokeQueued(_widget, [=] {
|
||||||
windowController->showSection(
|
window->showSection(
|
||||||
Memento(peerId, section),
|
Memento(peerId, section),
|
||||||
Window::SectionShow(
|
Window::SectionShow(
|
||||||
Window::SectionShow::Way::Backward,
|
Window::SectionShow::Way::Backward,
|
||||||
|
@ -162,13 +192,13 @@ void Controller::showSection(
|
||||||
Window::SectionMemento &&memento,
|
Window::SectionMemento &&memento,
|
||||||
const Window::SectionShow ¶ms) {
|
const Window::SectionShow ¶ms) {
|
||||||
if (!_widget->showInternal(&memento, params)) {
|
if (!_widget->showInternal(&memento, params)) {
|
||||||
_window->showSection(std::move(memento), params);
|
AbstractController::showSection(std::move(memento), params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::showBackFromStack(const Window::SectionShow ¶ms) {
|
void Controller::showBackFromStack(const Window::SectionShow ¶ms) {
|
||||||
if (!_widget->showBackFromStackInternal(params)) {
|
if (!_widget->showBackFromStackInternal(params)) {
|
||||||
_window->showBackFromStack(params);
|
AbstractController::showBackFromStack(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,26 +67,62 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Controller : public Window::Navigation {
|
class AbstractController : public Window::Navigation {
|
||||||
|
public:
|
||||||
|
AbstractController(not_null<Window::Controller*> parent)
|
||||||
|
: _parent(parent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual not_null<PeerData*> peer() const = 0;
|
||||||
|
virtual PeerData *migrated() const = 0;
|
||||||
|
virtual Section section() const = 0;
|
||||||
|
|
||||||
|
PeerId peerId() const {
|
||||||
|
return peer()->id;
|
||||||
|
}
|
||||||
|
PeerId migratedPeerId() const {
|
||||||
|
if (auto peer = migrated()) {
|
||||||
|
return peer->id;
|
||||||
|
}
|
||||||
|
return PeerId(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setSearchEnabledByContent(bool enabled) {
|
||||||
|
}
|
||||||
|
virtual rpl::producer<SparseIdsMergedSlice> mediaSource(
|
||||||
|
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||||
|
int limitBefore,
|
||||||
|
int limitAfter) const;
|
||||||
|
virtual rpl::producer<QString> mediaSourceQueryValue() const;
|
||||||
|
|
||||||
|
void showSection(
|
||||||
|
Window::SectionMemento &&memento,
|
||||||
|
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
||||||
|
void showBackFromStack(
|
||||||
|
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
||||||
|
not_null<Window::Controller*> parentController() override {
|
||||||
|
return _parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
not_null<Window::Controller*> _parent;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Controller : public AbstractController {
|
||||||
public:
|
public:
|
||||||
Controller(
|
Controller(
|
||||||
not_null<WrapWidget*> widget,
|
not_null<WrapWidget*> widget,
|
||||||
not_null<Window::Controller*> window,
|
not_null<Window::Controller*> window,
|
||||||
not_null<ContentMemento*> memento);
|
not_null<ContentMemento*> memento);
|
||||||
|
|
||||||
not_null<PeerData*> peer() const {
|
not_null<PeerData*> peer() const override {
|
||||||
return _peer;
|
return _peer;
|
||||||
}
|
}
|
||||||
PeerData *migrated() const {
|
PeerData *migrated() const override {
|
||||||
return _migrated;
|
return _migrated;
|
||||||
}
|
}
|
||||||
PeerId peerId() const {
|
Section section() const override {
|
||||||
return _peer->id;
|
|
||||||
}
|
|
||||||
PeerId migratedPeerId() const {
|
|
||||||
return _migrated ? _migrated->id : PeerId(0);
|
|
||||||
}
|
|
||||||
const Section §ion() const {
|
|
||||||
return _section;
|
return _section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,21 +133,18 @@ public:
|
||||||
rpl::producer<Wrap> wrapValue() const;
|
rpl::producer<Wrap> wrapValue() const;
|
||||||
void setSection(not_null<ContentMemento*> memento);
|
void setSection(not_null<ContentMemento*> memento);
|
||||||
|
|
||||||
not_null<Window::Controller*> window() const {
|
|
||||||
return _window;
|
|
||||||
}
|
|
||||||
Ui::SearchFieldController *searchFieldController() const {
|
Ui::SearchFieldController *searchFieldController() const {
|
||||||
return _searchFieldController.get();
|
return _searchFieldController.get();
|
||||||
}
|
}
|
||||||
void setSearchEnabledByContent(bool enabled) {
|
void setSearchEnabledByContent(bool enabled) override {
|
||||||
_seachEnabledByContent = enabled;
|
_seachEnabledByContent = enabled;
|
||||||
}
|
}
|
||||||
rpl::producer<bool> searchEnabledByContent() const;
|
rpl::producer<bool> searchEnabledByContent() const;
|
||||||
rpl::producer<SparseIdsMergedSlice> mediaSource(
|
rpl::producer<SparseIdsMergedSlice> mediaSource(
|
||||||
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||||
int limitBefore,
|
int limitBefore,
|
||||||
int limitAfter) const;
|
int limitAfter) const override;
|
||||||
rpl::producer<QString> mediaSourceQueryValue() const;
|
rpl::producer<QString> mediaSourceQueryValue() const override;
|
||||||
bool takeSearchStartsFocused() {
|
bool takeSearchStartsFocused() {
|
||||||
return base::take(_searchStartsFocused);
|
return base::take(_searchStartsFocused);
|
||||||
}
|
}
|
||||||
|
@ -123,9 +156,6 @@ public:
|
||||||
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
||||||
void showBackFromStack(
|
void showBackFromStack(
|
||||||
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
const Window::SectionShow ¶ms = Window::SectionShow()) override;
|
||||||
not_null<Window::Controller*> parentController() override {
|
|
||||||
return _window;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
|
@ -143,7 +173,6 @@ private:
|
||||||
not_null<WrapWidget*> _widget;
|
not_null<WrapWidget*> _widget;
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
PeerData *_migrated = nullptr;
|
PeerData *_migrated = nullptr;
|
||||||
not_null<Window::Controller*> _window;
|
|
||||||
rpl::variable<Wrap> _wrap;
|
rpl::variable<Wrap> _wrap;
|
||||||
Section _section;
|
Section _section;
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ void WrapWidget::startInjectingActivePeerProfiles() {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_wrap.value(),
|
_wrap.value(),
|
||||||
_controller->window()->activePeer.value())
|
_controller->parentController()->activePeer.value())
|
||||||
| rpl::filter((_1 == Wrap::Side) && (_2 != nullptr))
|
| rpl::filter((_1 == Wrap::Side) && (_2 != nullptr))
|
||||||
| rpl::map(_2)
|
| rpl::map(_2)
|
||||||
| rpl::start_with_next([this](not_null<PeerData*> peer) {
|
| rpl::start_with_next([this](not_null<PeerData*> peer) {
|
||||||
|
@ -241,7 +241,7 @@ void WrapWidget::forceContentRepaint() {
|
||||||
// _anotherTabMemento = createTabMemento(tab);
|
// _anotherTabMemento = createTabMemento(tab);
|
||||||
// }
|
// }
|
||||||
// auto newController = createController(
|
// auto newController = createController(
|
||||||
// _controller->window(),
|
// _controller->parentController(),
|
||||||
// _anotherTabMemento.get());
|
// _anotherTabMemento.get());
|
||||||
// auto newContent = createContent(
|
// auto newContent = createContent(
|
||||||
// _anotherTabMemento.get(),
|
// _anotherTabMemento.get(),
|
||||||
|
@ -331,7 +331,7 @@ void WrapWidget::createTopBar() {
|
||||||
_topBar,
|
_topBar,
|
||||||
st::infoTopBarClose));
|
st::infoTopBarClose));
|
||||||
close->addClickHandler([this] {
|
close->addClickHandler([this] {
|
||||||
_controller->window()->closeThirdSection();
|
_controller->parentController()->closeThirdSection();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (wrapValue == Wrap::Layer) {
|
if (wrapValue == Wrap::Layer) {
|
||||||
|
@ -340,7 +340,7 @@ void WrapWidget::createTopBar() {
|
||||||
_topBar,
|
_topBar,
|
||||||
st::infoLayerTopBarClose));
|
st::infoLayerTopBarClose));
|
||||||
close->addClickHandler([this] {
|
close->addClickHandler([this] {
|
||||||
_controller->window()->hideSpecialLayer();
|
_controller->parentController()->hideSpecialLayer();
|
||||||
});
|
});
|
||||||
} else if (requireTopBarSearch()) {
|
} else if (requireTopBarSearch()) {
|
||||||
auto search = _controller->searchFieldController();
|
auto search = _controller->searchFieldController();
|
||||||
|
@ -465,7 +465,7 @@ void WrapWidget::showProfileMenu() {
|
||||||
_topBarMenuToggle->installEventFilter(_topBarMenu.get());
|
_topBarMenuToggle->installEventFilter(_topBarMenu.get());
|
||||||
|
|
||||||
Window::FillPeerMenu(
|
Window::FillPeerMenu(
|
||||||
_controller->window(),
|
_controller->parentController(),
|
||||||
_controller->peer(),
|
_controller->peer(),
|
||||||
[this](const QString &text, base::lambda<void()> callback) {
|
[this](const QString &text, base::lambda<void()> callback) {
|
||||||
return _topBarMenu->addAction(text, std::move(callback));
|
return _topBarMenu->addAction(text, std::move(callback));
|
||||||
|
@ -788,7 +788,7 @@ void WrapWidget::showNewContent(
|
||||||
&& (params.animated != anim::type::instant);
|
&& (params.animated != anim::type::instant);
|
||||||
auto animationParams = SectionSlideParams();
|
auto animationParams = SectionSlideParams();
|
||||||
auto newController = createController(
|
auto newController = createController(
|
||||||
_controller->window(),
|
_controller->parentController(),
|
||||||
memento);
|
memento);
|
||||||
auto newContent = object_ptr<ContentWidget>(nullptr);
|
auto newContent = object_ptr<ContentWidget>(nullptr);
|
||||||
if (needAnimation) {
|
if (needAnimation) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
|
#include "media/player/media_player_instance.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
|
@ -546,7 +547,7 @@ void ListWidget::Section::refreshHeight() {
|
||||||
|
|
||||||
ListWidget::ListWidget(
|
ListWidget::ListWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller)
|
not_null<AbstractController*> controller)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(_controller->peer())
|
, _peer(_controller->peer())
|
||||||
|
@ -594,6 +595,18 @@ rpl::producer<SelectedItems> ListWidget::selectedListValue() const {
|
||||||
collectSelectedItems());
|
collectSelectedItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect ListWidget::getCurrentSongGeometry() {
|
||||||
|
const auto type = AudioMsgId::Type::Song;
|
||||||
|
const auto current = ::Media::Player::instance()->current(type);
|
||||||
|
const auto fullMsgId = current.contextId();
|
||||||
|
if (fullMsgId && isPossiblyMyId(fullMsgId)) {
|
||||||
|
if (const auto item = findItemById(GetUniversalId(fullMsgId))) {
|
||||||
|
return item->geometry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QRect(0, 0, width(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ListWidget::restart() {
|
void ListWidget::restart() {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
|
|
||||||
|
@ -1347,6 +1360,7 @@ void ListWidget::showContextMenu(
|
||||||
_contextMenu = nullptr;
|
_contextMenu = nullptr;
|
||||||
mouseActionUpdate(QCursor::pos());
|
mouseActionUpdate(QCursor::pos());
|
||||||
repaintItem(universalId);
|
repaintItem(universalId);
|
||||||
|
_checkForHide.fire({});
|
||||||
}));
|
}));
|
||||||
_contextMenu->popup(e->globalPos());
|
_contextMenu->popup(e->globalPos());
|
||||||
e->accept();
|
e->accept();
|
||||||
|
@ -1373,12 +1387,14 @@ void ListWidget::forwardItem(UniversalMsgId universalId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::forwardItems(MessageIdsList &&items) {
|
void ListWidget::forwardItems(MessageIdsList &&items) {
|
||||||
const auto weak = make_weak(this);
|
auto callback = [weak = make_weak(this)] {
|
||||||
Window::ShowForwardMessagesBox(std::move(items), [weak] {
|
|
||||||
if (const auto strong = weak.data()) {
|
if (const auto strong = weak.data()) {
|
||||||
strong->clearSelected();
|
strong->clearSelected();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
setActionBoxWeak(Window::ShowForwardMessagesBox(
|
||||||
|
std::move(items),
|
||||||
|
std::move(callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::deleteSelected() {
|
void ListWidget::deleteSelected() {
|
||||||
|
@ -1393,7 +1409,19 @@ void ListWidget::deleteItem(UniversalMsgId universalId) {
|
||||||
|
|
||||||
void ListWidget::deleteItems(MessageIdsList &&items) {
|
void ListWidget::deleteItems(MessageIdsList &&items) {
|
||||||
if (!items.empty()) {
|
if (!items.empty()) {
|
||||||
Ui::show(Box<DeleteMessagesBox>(std::move(items)));
|
const auto box = Ui::show(Box<DeleteMessagesBox>(std::move(items)));
|
||||||
|
setActionBoxWeak(box.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListWidget::setActionBoxWeak(QPointer<Ui::RpWidget> box) {
|
||||||
|
if ((_actionBoxWeak = box)) {
|
||||||
|
_actionBoxWeakLifetime = _actionBoxWeak->alive(
|
||||||
|
) | rpl::start_with_done([weak = make_weak(this)]{
|
||||||
|
if (weak) {
|
||||||
|
weak->_checkForHide.fire({});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1768,8 +1796,8 @@ void ListWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butto
|
||||||
auto pressLayout = _overLayout;
|
auto pressLayout = _overLayout;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->window()->window()->wasInactivePress();
|
_pressWasInactive = _controller->parentController()->window()->wasInactivePress();
|
||||||
if (_pressWasInactive) _controller->window()->window()->setInactivePress(false);
|
if (_pressWasInactive) _controller->parentController()->window()->setInactivePress(false);
|
||||||
|
|
||||||
if (ClickHandler::getPressed() && !hasSelected()) {
|
if (ClickHandler::getPressed() && !hasSelected()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
@ -1893,7 +1921,7 @@ void ListWidget::performDrag() {
|
||||||
// mimeData->setData(qsl("application/x-td-forward-selected"), "1");
|
// mimeData->setData(qsl("application/x-td-forward-selected"), "1");
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// _controller->window()->launchDrag(std::move(mimeData));
|
// _controller->parentController()->window()->launchDrag(std::move(mimeData));
|
||||||
// return;
|
// return;
|
||||||
//} else {
|
//} else {
|
||||||
// auto forwardMimeType = QString();
|
// auto forwardMimeType = QString();
|
||||||
|
@ -1924,7 +1952,7 @@ void ListWidget::performDrag() {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // This call enters event loop and can destroy any QObject.
|
// // This call enters event loop and can destroy any QObject.
|
||||||
// _controller->window()->launchDrag(std::move(mimeData));
|
// _controller->parentController()->window()->launchDrag(std::move(mimeData));
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
@ -1974,7 +2002,7 @@ void ListWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton butt
|
||||||
if (selection.text != FullSelection
|
if (selection.text != FullSelection
|
||||||
&& selection.text.from == selection.text.to) {
|
&& selection.text.from == selection.text.to) {
|
||||||
clearSelected();
|
clearSelected();
|
||||||
//_controller->window()->setInnerFocus(); // #TODO focus
|
//_controller->parentController()->window()->setInnerFocus(); // #TODO focus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Controller;
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
class Controller;
|
class AbstractController;
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class ListWidget : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
ListWidget(
|
ListWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller);
|
not_null<AbstractController*> controller);
|
||||||
|
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
|
@ -61,6 +61,14 @@ public:
|
||||||
clearSelected();
|
clearSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect getCurrentSongGeometry();
|
||||||
|
rpl::producer<> checkForHide() const {
|
||||||
|
return _checkForHide.events();
|
||||||
|
}
|
||||||
|
bool preventAutoHide() const {
|
||||||
|
return (_contextMenu != nullptr) || (_actionBoxWeak != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void saveState(not_null<Memento*> memento);
|
void saveState(not_null<Memento*> memento);
|
||||||
void restoreState(not_null<Memento*> memento);
|
void restoreState(not_null<Memento*> memento);
|
||||||
|
|
||||||
|
@ -259,7 +267,9 @@ private:
|
||||||
void validateTrippleClickStartTime();
|
void validateTrippleClickStartTime();
|
||||||
void checkMoveToOtherViewer();
|
void checkMoveToOtherViewer();
|
||||||
|
|
||||||
const not_null<Controller*> _controller;
|
void setActionBoxWeak(QPointer<Ui::RpWidget> box);
|
||||||
|
|
||||||
|
const not_null<AbstractController*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
PeerData * const _migrated = nullptr;
|
PeerData * const _migrated = nullptr;
|
||||||
Type _type = Type::Photo;
|
Type _type = Type::Photo;
|
||||||
|
@ -294,7 +304,11 @@ private:
|
||||||
style::cursor _cursor = style::cur_default;
|
style::cursor _cursor = style::cur_default;
|
||||||
DragSelectAction _dragSelectAction = DragSelectAction::None;
|
DragSelectAction _dragSelectAction = DragSelectAction::None;
|
||||||
bool _wasSelectedText = false; // was some text selected in current drag action
|
bool _wasSelectedText = false; // was some text selected in current drag action
|
||||||
|
|
||||||
Ui::PopupMenu *_contextMenu = nullptr;
|
Ui::PopupMenu *_contextMenu = nullptr;
|
||||||
|
rpl::event_stream<> _checkForHide;
|
||||||
|
QPointer<Ui::RpWidget> _actionBoxWeak;
|
||||||
|
rpl::lifetime _actionBoxWeakLifetime;
|
||||||
|
|
||||||
QPoint _trippleClickPoint;
|
QPoint _trippleClickPoint;
|
||||||
TimeMs _trippleClickStartTime = 0;
|
TimeMs _trippleClickStartTime = 0;
|
||||||
|
|
|
@ -325,7 +325,7 @@ Ui::MultiSlideTracker DetailsFiller::fillUserButtons(
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
Ui::MultiSlideTracker tracker;
|
Ui::MultiSlideTracker tracker;
|
||||||
auto window = _controller->window();
|
auto window = _controller->parentController();
|
||||||
|
|
||||||
auto addSendMessageButton = [&] {
|
auto addSendMessageButton = [&] {
|
||||||
auto sendMessageVisible = rpl::combine(
|
auto sendMessageVisible = rpl::combine(
|
||||||
|
@ -377,7 +377,7 @@ Ui::MultiSlideTracker DetailsFiller::fillChannelButtons(
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
Ui::MultiSlideTracker tracker;
|
Ui::MultiSlideTracker tracker;
|
||||||
auto window = _controller->window();
|
auto window = _controller->parentController();
|
||||||
auto viewChannelVisible = rpl::combine(
|
auto viewChannelVisible = rpl::combine(
|
||||||
_controller->wrapValue(),
|
_controller->wrapValue(),
|
||||||
window->historyPeer.value(),
|
window->historyPeer.value(),
|
||||||
|
|
|
@ -234,7 +234,7 @@ Cover::Cover(
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _userpic(
|
, _userpic(
|
||||||
this,
|
this,
|
||||||
controller->window(),
|
controller->parentController(),
|
||||||
_peer,
|
_peer,
|
||||||
Ui::UserpicButton::Role::OpenPhoto,
|
Ui::UserpicButton::Role::OpenPhoto,
|
||||||
st::infoProfilePhoto)
|
st::infoProfilePhoto)
|
||||||
|
|
|
@ -74,7 +74,7 @@ Members::Members(
|
||||||
| rpl::start_with_next([this](int count) {
|
| rpl::start_with_next([this](int count) {
|
||||||
const auto enabled = (count >= kEnableSearchMembersAfterCount);
|
const auto enabled = (count >= kEnableSearchMembersAfterCount);
|
||||||
_controller->setSearchEnabledByContent(enabled);
|
_controller->setSearchEnabledByContent(enabled);
|
||||||
});
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Members::desiredHeight() const {
|
int Members::desiredHeight() const {
|
||||||
|
|
|
@ -198,8 +198,11 @@ MainWidget::MainWidget(
|
||||||
, _sideShadow(this)
|
, _sideShadow(this)
|
||||||
, _dialogs(this, _controller)
|
, _dialogs(this, _controller)
|
||||||
, _history(this, _controller)
|
, _history(this, _controller)
|
||||||
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
|
, _playerPlaylist(
|
||||||
, _playerPanel(this, Media::Player::Panel::Layout::Full) {
|
this,
|
||||||
|
_controller,
|
||||||
|
Media::Player::Panel::Layout::OnlyPlaylist)
|
||||||
|
, _playerPanel(this, _controller, Media::Player::Panel::Layout::Full) {
|
||||||
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
|
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
|
||||||
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
|
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ mediaPlayerPanelVolumeToggleTop: 57px;
|
||||||
|
|
||||||
mediaPlayerScroll: ScrollArea(defaultSolidScroll) {
|
mediaPlayerScroll: ScrollArea(defaultSolidScroll) {
|
||||||
deltat: 10px;
|
deltat: 10px;
|
||||||
deltab: 0px;
|
deltab: 10px;
|
||||||
}
|
}
|
||||||
mediaPlayerListHeightMax: 280px;
|
mediaPlayerListHeightMax: 280px;
|
||||||
mediaPlayerListMarginBottom: 10px;
|
mediaPlayerListMarginBottom: 10px;
|
||||||
|
|
|
@ -199,7 +199,7 @@ auto Instance::playlistKey(not_null<Data*> data) const
|
||||||
-> base::optional<SliceKey> {
|
-> base::optional<SliceKey> {
|
||||||
const auto contextId = data->current.contextId();
|
const auto contextId = data->current.contextId();
|
||||||
const auto history = data->history;
|
const auto history = data->history;
|
||||||
if (!contextId || !history) {
|
if (!contextId || !history || !IsServerMsgId(contextId.msg)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,25 +22,36 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "media/player/media_player_cover.h"
|
#include "media/player/media_player_cover.h"
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
#include "styles/style_overview.h"
|
#include "info/media/info_media_list_widget.h"
|
||||||
#include "styles/style_widgets.h"
|
|
||||||
#include "styles/style_media_player.h"
|
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "styles/style_overview.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
#include "styles/style_media_player.h"
|
||||||
|
#include "styles/style_info.h"
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Player {
|
namespace Player {
|
||||||
|
namespace {
|
||||||
|
|
||||||
Panel::Panel(QWidget *parent, Layout layout) : TWidget(parent)
|
using ListWidget = Info::Media::ListWidget;
|
||||||
|
|
||||||
|
constexpr auto kPlaylistIdsLimit = 32;
|
||||||
|
constexpr auto kDelayedHideTimeout = TimeMs(3000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Panel::Panel(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
|
Layout layout)
|
||||||
|
: RpWidget(parent)
|
||||||
|
, AbstractController(window)
|
||||||
, _layout(layout)
|
, _layout(layout)
|
||||||
|
, _showTimer([this] { startShow(); })
|
||||||
|
, _hideTimer([this] { startHideChecked(); })
|
||||||
, _scroll(this, st::mediaPlayerScroll) {
|
, _scroll(this, st::mediaPlayerScroll) {
|
||||||
_hideTimer.setSingleShot(true);
|
|
||||||
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideStart()));
|
|
||||||
|
|
||||||
_showTimer.setSingleShot(true);
|
|
||||||
connect(&_showTimer, SIGNAL(timeout()), this, SLOT(onShowStart()));
|
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
updateSize();
|
updateSize();
|
||||||
}
|
}
|
||||||
|
@ -53,7 +64,7 @@ bool Panel::overlaps(const QRect &globalRect) {
|
||||||
return rect().marginsRemoved(QMargins(marginLeft, contentTop(), marginRight, contentBottom())).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
return rect().marginsRemoved(QMargins(marginLeft, contentTop(), marginRight, contentBottom())).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onWindowActiveChanged() {
|
void Panel::windowActiveChanged() {
|
||||||
if (!App::wnd()->windowHandle()->isActive() && !isHidden()) {
|
if (!App::wnd()->windowHandle()->isActive() && !isHidden()) {
|
||||||
leaveEvent(nullptr);
|
leaveEvent(nullptr);
|
||||||
}
|
}
|
||||||
|
@ -63,16 +74,36 @@ void Panel::resizeEvent(QResizeEvent *e) {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onListHeightUpdated() {
|
void Panel::listHeightUpdated(int newHeight) {
|
||||||
if (auto widget = _scroll->widget()) {
|
if (newHeight > emptyInnerHeight() || _cover) {
|
||||||
if (widget->height() > 0 || _cover) {
|
updateSize();
|
||||||
updateSize();
|
} else {
|
||||||
} else {
|
_hideTimer.callOnce(0);
|
||||||
hideIgnoringEnterEvents();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Panel::contentTooSmall() const {
|
||||||
|
const auto innerHeight = _scroll->widget()
|
||||||
|
? _scroll->widget()->height()
|
||||||
|
: emptyInnerHeight();
|
||||||
|
return (innerHeight <= emptyInnerHeight() && !_cover);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Panel::emptyInnerHeight() const {
|
||||||
|
return st::infoMediaMargin.top()
|
||||||
|
+ st::overviewFileLayout.songPadding.top()
|
||||||
|
+ st::overviewFileLayout.songThumbSize
|
||||||
|
+ st::overviewFileLayout.songPadding.bottom()
|
||||||
|
+ st::infoMediaMargin.bottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Panel::preventAutoHide() const {
|
||||||
|
if (const auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||||
|
return list->preventAutoHide();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::updateControlsGeometry() {
|
void Panel::updateControlsGeometry() {
|
||||||
auto scrollTop = contentTop();
|
auto scrollTop = contentTop();
|
||||||
auto width = contentWidth();
|
auto width = contentWidth();
|
||||||
|
@ -91,7 +122,6 @@ void Panel::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
|
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
|
||||||
widget->resizeToWidth(width);
|
widget->resizeToWidth(width);
|
||||||
onScroll();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,19 +133,9 @@ int Panel::bestPositionFor(int left) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::scrollPlaylistToCurrentTrack() {
|
void Panel::scrollPlaylistToCurrentTrack() {
|
||||||
// #TODO playlist
|
if (const auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||||
//if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
const auto rect = list->getCurrentSongGeometry();
|
||||||
// auto rect = list->getCurrentTrackGeometry();
|
_scroll->scrollToY(rect.y() - st::infoMediaMargin.top());
|
||||||
// auto top = _scroll->scrollTop(), bottom = top + _scroll->height();
|
|
||||||
// _scroll->scrollToY(rect.y());
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::onScroll() {
|
|
||||||
if (auto widget = static_cast<TWidget*>(_scroll->widget())) {
|
|
||||||
int visibleTop = _scroll->scrollTop();
|
|
||||||
int visibleBottom = visibleTop + _scroll->height();
|
|
||||||
widget->setVisibleTopBottom(visibleTop, visibleBottom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,42 +190,45 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::enterEventHook(QEvent *e) {
|
void Panel::enterEventHook(QEvent *e) {
|
||||||
if (_ignoringEnterEvents) return;
|
if (_ignoringEnterEvents || contentTooSmall()) return;
|
||||||
|
|
||||||
_hideTimer.stop();
|
_hideTimer.cancel();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onShowStart();
|
startShow();
|
||||||
} else {
|
} else {
|
||||||
_showTimer.start(0);
|
_showTimer.callOnce(0);
|
||||||
}
|
}
|
||||||
return TWidget::enterEventHook(e);
|
return TWidget::enterEventHook(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::leaveEventHook(QEvent *e) {
|
void Panel::leaveEventHook(QEvent *e) {
|
||||||
_showTimer.stop();
|
if (preventAutoHide()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_showTimer.cancel();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onHideStart();
|
startHide();
|
||||||
} else {
|
} else {
|
||||||
_hideTimer.start(300);
|
_hideTimer.callOnce(300);
|
||||||
}
|
}
|
||||||
return TWidget::leaveEventHook(e);
|
return TWidget::leaveEventHook(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::showFromOther() {
|
void Panel::showFromOther() {
|
||||||
_hideTimer.stop();
|
_hideTimer.cancel();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onShowStart();
|
startShow();
|
||||||
} else {
|
} else {
|
||||||
_showTimer.start(300);
|
_showTimer.callOnce(300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::hideFromOther() {
|
void Panel::hideFromOther() {
|
||||||
_showTimer.stop();
|
_showTimer.cancel();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onHideStart();
|
startHide();
|
||||||
} else {
|
} else {
|
||||||
_hideTimer.start(0);
|
_hideTimer.callOnce(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,32 +242,108 @@ void Panel::ensureCreated() {
|
||||||
|
|
||||||
_scrollShadow.create(this, st::mediaPlayerScrollShadow, RectPart::Bottom);
|
_scrollShadow.create(this, st::mediaPlayerScrollShadow, RectPart::Bottom);
|
||||||
}
|
}
|
||||||
// #TODO playlist
|
_refreshListLifetime = instance()->playlistChanges(
|
||||||
//auto list = object_ptr<ListWidget>(this);
|
AudioMsgId::Type::Song
|
||||||
//connect(list, SIGNAL(heightUpdated()), this, SLOT(onListHeightUpdated()));
|
) | rpl::start_with_next([this] {
|
||||||
//_scroll->setOwnedWidget(std::move(list));
|
refreshList();
|
||||||
|
});
|
||||||
|
refreshList();
|
||||||
|
|
||||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
if (auto window = App::wnd()) {
|
if (const auto window = App::wnd()) {
|
||||||
connect(window->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
|
connect(
|
||||||
|
window->windowHandle(),
|
||||||
|
&QWindow::activeChanged,
|
||||||
|
this,
|
||||||
|
&Panel::windowActiveChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize();
|
|
||||||
updateControlsGeometry();
|
|
||||||
_ignoringEnterEvents = false;
|
_ignoringEnterEvents = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panel::refreshList() {
|
||||||
|
const auto current = instance()->current(AudioMsgId::Type::Song);
|
||||||
|
const auto contextId = current.contextId();
|
||||||
|
const auto peer = [&]() -> PeerData* {
|
||||||
|
const auto item = contextId ? App::histItemById(contextId) : nullptr;
|
||||||
|
if (item) {
|
||||||
|
const auto result = item->history()->peer;
|
||||||
|
if (const auto migrated = result->migrateTo()) {
|
||||||
|
return migrated;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
const auto migrated = peer ? peer->migrateFrom() : nullptr;
|
||||||
|
if (_listPeer != peer || _listMigratedPeer != migrated) {
|
||||||
|
_scroll->takeWidget<QWidget>().destroy();
|
||||||
|
_listPeer = _listMigratedPeer = nullptr;
|
||||||
|
}
|
||||||
|
if (peer && !_listPeer) {
|
||||||
|
_listPeer = peer;
|
||||||
|
_listMigratedPeer = migrated;
|
||||||
|
auto list = object_ptr<ListWidget>(this, infoController());
|
||||||
|
|
||||||
|
const auto weak = _scroll->setOwnedWidget(std::move(list));
|
||||||
|
|
||||||
|
updateSize();
|
||||||
|
updateControlsGeometry();
|
||||||
|
|
||||||
|
weak->checkForHide(
|
||||||
|
) | rpl::start_with_next([this] {
|
||||||
|
if (!rect().contains(mapFromGlobal(QCursor::pos()))) {
|
||||||
|
_hideTimer.callOnce(kDelayedHideTimeout);
|
||||||
|
}
|
||||||
|
}, weak->lifetime());
|
||||||
|
|
||||||
|
weak->heightValue(
|
||||||
|
) | rpl::start_with_next([this](int newHeight) {
|
||||||
|
listHeightUpdated(newHeight);
|
||||||
|
}, weak->lifetime());
|
||||||
|
|
||||||
|
weak->scrollToRequests(
|
||||||
|
) | rpl::start_with_next([this](int newScrollTop) {
|
||||||
|
_scroll->scrollToY(newScrollTop);
|
||||||
|
}, weak->lifetime());
|
||||||
|
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
rpl::combine(
|
||||||
|
_scroll->scrollTopValue(),
|
||||||
|
_scroll->heightValue(),
|
||||||
|
tuple(_1, _1 + _2)
|
||||||
|
) | rpl::start_with_next([=](int top, int bottom) {
|
||||||
|
weak->setVisibleTopBottom(top, bottom);
|
||||||
|
}, weak->lifetime());
|
||||||
|
|
||||||
|
auto memento = Info::Media::Memento(
|
||||||
|
peerId(),
|
||||||
|
migratedPeerId(),
|
||||||
|
section().mediaType());
|
||||||
|
memento.setAroundId(contextId);
|
||||||
|
memento.setIdsLimit(kPlaylistIdsLimit);
|
||||||
|
memento.setScrollTopItem(contextId);
|
||||||
|
memento.setScrollTopShift(-st::infoMediaMargin.top());
|
||||||
|
weak->restoreState(&memento);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::performDestroy() {
|
void Panel::performDestroy() {
|
||||||
if (!_scroll->widget()) return;
|
if (!_scroll->widget()) return;
|
||||||
|
|
||||||
_cover.destroy();
|
_cover.destroy();
|
||||||
// #TODO playlist
|
_scroll->takeWidget<QWidget>().destroy();
|
||||||
//_scroll->takeWidget<ListWidget>().destroyDelayed();
|
_listPeer = _listMigratedPeer = nullptr;
|
||||||
|
_refreshListLifetime.destroy();
|
||||||
|
|
||||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
if (auto window = App::wnd()) {
|
if (const auto window = App::wnd()) {
|
||||||
disconnect(window->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
|
disconnect(
|
||||||
|
window->windowHandle(),
|
||||||
|
&QWindow::activeChanged,
|
||||||
|
this,
|
||||||
|
&Panel::windowActiveChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,12 +362,22 @@ void Panel::setCloseCallback(ButtonCallback &&callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onShowStart() {
|
not_null<PeerData*> Panel::peer() const {
|
||||||
|
return _listPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerData *Panel::migrated() const {
|
||||||
|
return _listMigratedPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info::Section Panel::section() const {
|
||||||
|
return Info::Section(Info::Section::MediaType::MusicFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::startShow() {
|
||||||
ensureCreated();
|
ensureCreated();
|
||||||
if (auto widget = _scroll->widget()) {
|
if (contentTooSmall()) {
|
||||||
if (widget->height() <= 0 && !_cover) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
|
@ -286,11 +395,22 @@ void Panel::hideIgnoringEnterEvents() {
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
hideFinished();
|
hideFinished();
|
||||||
} else {
|
} else {
|
||||||
onHideStart();
|
startHide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onHideStart() {
|
void Panel::startHideChecked() {
|
||||||
|
if (!contentTooSmall() && preventAutoHide()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isHidden()) {
|
||||||
|
hideFinished();
|
||||||
|
} else {
|
||||||
|
startHide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::startHide() {
|
||||||
if (_hiding || isHidden()) return;
|
if (_hiding || isHidden()) return;
|
||||||
|
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
|
@ -340,7 +460,7 @@ int Panel::contentBottom() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Panel::scrollMarginBottom() const {
|
int Panel::scrollMarginBottom() const {
|
||||||
return st::mediaPlayerPanelMarginBottom;
|
return 0;// st::mediaPlayerPanelMarginBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
|
|
|
@ -20,6 +20,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
class Controller;
|
||||||
|
} // namespace Window
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ScrollArea;
|
class ScrollArea;
|
||||||
class Shadow;
|
class Shadow;
|
||||||
|
@ -30,15 +38,16 @@ namespace Player {
|
||||||
|
|
||||||
class CoverWidget;
|
class CoverWidget;
|
||||||
|
|
||||||
class Panel : public TWidget {
|
class Panel : public Ui::RpWidget, private Info::AbstractController {
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Layout {
|
enum class Layout {
|
||||||
Full,
|
Full,
|
||||||
OnlyPlaylist,
|
OnlyPlaylist,
|
||||||
};
|
};
|
||||||
Panel(QWidget *parent, Layout layout);
|
Panel(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::Controller*> controller,
|
||||||
|
Layout layout);
|
||||||
|
|
||||||
bool overlaps(const QRect &globalRect);
|
bool overlaps(const QRect &globalRect);
|
||||||
|
|
||||||
|
@ -59,20 +68,26 @@ protected:
|
||||||
void enterEventHook(QEvent *e) override;
|
void enterEventHook(QEvent *e) override;
|
||||||
void leaveEventHook(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onShowStart();
|
|
||||||
void onHideStart();
|
|
||||||
|
|
||||||
void onScroll();
|
|
||||||
void onListHeightUpdated();
|
|
||||||
void onWindowActiveChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Info::AbstractController implementation.
|
||||||
|
not_null<PeerData*> peer() const override;
|
||||||
|
PeerData *migrated() const override;
|
||||||
|
Info::Section section() const override;
|
||||||
|
|
||||||
|
void startShow();
|
||||||
|
void startHide();
|
||||||
|
void startHideChecked();
|
||||||
|
bool preventAutoHide() const;
|
||||||
|
void listHeightUpdated(int newHeight);
|
||||||
|
int emptyInnerHeight() const;
|
||||||
|
bool contentTooSmall() const;
|
||||||
|
void windowActiveChanged();
|
||||||
|
|
||||||
void ensureCreated();
|
void ensureCreated();
|
||||||
void performDestroy();
|
void performDestroy();
|
||||||
|
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
void refreshList();
|
||||||
void updateSize();
|
void updateSize();
|
||||||
void appearanceCallback();
|
void appearanceCallback();
|
||||||
void hideFinished();
|
void hideFinished();
|
||||||
|
@ -90,6 +105,9 @@ private:
|
||||||
|
|
||||||
void startAnimation();
|
void startAnimation();
|
||||||
void scrollPlaylistToCurrentTrack();
|
void scrollPlaylistToCurrentTrack();
|
||||||
|
not_null<Info::AbstractController*> infoController() {
|
||||||
|
return static_cast<Info::AbstractController*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
Layout _layout;
|
Layout _layout;
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
|
@ -99,13 +117,18 @@ private:
|
||||||
|
|
||||||
bool _ignoringEnterEvents = false;
|
bool _ignoringEnterEvents = false;
|
||||||
|
|
||||||
QTimer _hideTimer, _showTimer;
|
base::Timer _showTimer;
|
||||||
|
base::Timer _hideTimer;
|
||||||
|
|
||||||
ButtonCallback _pinCallback, _closeCallback;
|
ButtonCallback _pinCallback, _closeCallback;
|
||||||
object_ptr<CoverWidget> _cover = { nullptr };
|
object_ptr<CoverWidget> _cover = { nullptr };
|
||||||
object_ptr<Ui::ScrollArea> _scroll;
|
object_ptr<Ui::ScrollArea> _scroll;
|
||||||
object_ptr<Ui::Shadow> _scrollShadow = { nullptr };
|
object_ptr<Ui::Shadow> _scrollShadow = { nullptr };
|
||||||
|
|
||||||
|
rpl::lifetime _refreshListLifetime;
|
||||||
|
PeerData *_listPeer = nullptr;
|
||||||
|
PeerData *_listMigratedPeer = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Clip
|
} // namespace Clip
|
||||||
|
|
|
@ -457,7 +457,7 @@ void PeerMenuShareContactBox(not_null<UserData*> user) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowForwardMessagesBox(
|
QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
MessageIdsList &&items,
|
MessageIdsList &&items,
|
||||||
base::lambda_once<void()> &&successCallback) {
|
base::lambda_once<void()> &&successCallback) {
|
||||||
const auto weak = std::make_shared<QPointer<PeerListBox>>();
|
const auto weak = std::make_shared<QPointer<PeerListBox>>();
|
||||||
|
@ -493,6 +493,7 @@ void ShowForwardMessagesBox(
|
||||||
*weak = Ui::show(Box<PeerListBox>(
|
*weak = Ui::show(Box<PeerListBox>(
|
||||||
std::make_unique<ChooseRecipientBoxController>(std::move(callback)),
|
std::make_unique<ChooseRecipientBoxController>(std::move(callback)),
|
||||||
std::move(initBox)), LayerOption::KeepOther);
|
std::move(initBox)), LayerOption::KeepOther);
|
||||||
|
return weak->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerMenuAddChannelMembers(not_null<ChannelData*> channel) {
|
void PeerMenuAddChannelMembers(not_null<ChannelData*> channel) {
|
||||||
|
|
|
@ -20,6 +20,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
class Controller;
|
class Controller;
|
||||||
|
@ -48,7 +52,7 @@ void PeerMenuAddChannelMembers(not_null<ChannelData*> channel);
|
||||||
base::lambda<void()> ClearHistoryHandler(not_null<PeerData*> peer);
|
base::lambda<void()> ClearHistoryHandler(not_null<PeerData*> peer);
|
||||||
base::lambda<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer);
|
base::lambda<void()> DeleteAndLeaveHandler(not_null<PeerData*> peer);
|
||||||
|
|
||||||
void ShowForwardMessagesBox(
|
QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
MessageIdsList &&items,
|
MessageIdsList &&items,
|
||||||
base::lambda_once<void()> &&successCallback = nullptr);
|
base::lambda_once<void()> &&successCallback = nullptr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue