mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Playlist appearance added to the new media player.
Also itemRemoved() now is fired as a global observable.
This commit is contained in:
parent
4f0cff5467
commit
31a847fb9d
38 changed files with 677 additions and 271 deletions
BIN
Telegram/Resources/icons/playlist_shadow.png
Normal file
BIN
Telegram/Resources/icons/playlist_shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 B |
BIN
Telegram/Resources/icons/playlist_shadow@2x.png
Normal file
BIN
Telegram/Resources/icons/playlist_shadow@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 B |
|
@ -2018,8 +2018,8 @@ namespace {
|
||||||
if (auto manager = Window::Notifications::manager()) {
|
if (auto manager = Window::Notifications::manager()) {
|
||||||
manager->clearFromItem(item);
|
manager->clearFromItem(item);
|
||||||
}
|
}
|
||||||
if (App::main() && !App::quitting()) {
|
if (Global::started() && !App::quitting()) {
|
||||||
App::main()->itemRemoved(item);
|
Global::RefItemRemoved().notify(item, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/vector_of_moveable.h"
|
#include "core/vector_of_moveable.h"
|
||||||
|
#include "core/type_traits.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -30,9 +31,12 @@ void RegisterPendingObservable(ObservableCallHandlers *handlers);
|
||||||
void UnregisterActiveObservable(ObservableCallHandlers *handlers);
|
void UnregisterActiveObservable(ObservableCallHandlers *handlers);
|
||||||
void UnregisterObservable(ObservableCallHandlers *handlers);
|
void UnregisterObservable(ObservableCallHandlers *handlers);
|
||||||
|
|
||||||
|
template <typename EventType>
|
||||||
|
using EventParamType = typename base::type_traits<EventType>::parameter_type;
|
||||||
|
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
struct SubscriptionHandlerHelper {
|
struct SubscriptionHandlerHelper {
|
||||||
using type = base::lambda_unique<void(const EventType &)>;
|
using type = base::lambda_unique<void(EventParamType<EventType>)>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -67,6 +71,9 @@ public:
|
||||||
qSwap(_removeMethod, other._removeMethod);
|
qSwap(_removeMethod, other._removeMethod);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (_node != nullptr);
|
||||||
|
}
|
||||||
void destroy() {
|
void destroy() {
|
||||||
if (_node) {
|
if (_node) {
|
||||||
(*_removeMethod)(_node);
|
(*_removeMethod)(_node);
|
||||||
|
@ -128,14 +135,26 @@ private:
|
||||||
|
|
||||||
template <typename EventType, typename Handler = internal::SubscriptionHandler<EventType>>
|
template <typename EventType, typename Handler = internal::SubscriptionHandler<EventType>>
|
||||||
class Observable : public internal::CommonObservable<EventType, Handler> {
|
class Observable : public internal::CommonObservable<EventType, Handler> {
|
||||||
|
using SimpleEventType = typename base::type_traits<EventType>::is_fast_copy_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
template <typename = std_::enable_if_t<!SimpleEventType::value>>
|
||||||
void notify(EventType &&event, bool sync = false) {
|
void notify(EventType &&event, bool sync = false) {
|
||||||
if (this->_data) {
|
if (this->_data) {
|
||||||
this->_data->notify(std_::move(event), sync);
|
this->_data->notify(std_::move(event), sync);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename = std_::enable_if_t<!SimpleEventType::value>>
|
||||||
void notify(const EventType &event, bool sync = false) {
|
void notify(const EventType &event, bool sync = false) {
|
||||||
notify(EventType(event));
|
if (this->_data) {
|
||||||
|
this->_data->notify(EventType(event), sync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename = std_::enable_if_t<SimpleEventType::value>>
|
||||||
|
void notify(EventType event, bool sync = false) {
|
||||||
|
if (this->_data) {
|
||||||
|
this->_data->notify(std_::move(event), sync);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -338,7 +357,7 @@ protected:
|
||||||
template <typename EventType, typename Handler, typename Lambda>
|
template <typename EventType, typename Handler, typename Lambda>
|
||||||
int subscribe(base::Observable<EventType, Handler> &observable, Lambda &&handler) {
|
int subscribe(base::Observable<EventType, Handler> &observable, Lambda &&handler) {
|
||||||
_subscriptions.push_back(observable.add_subscription(std_::forward<Lambda>(handler)));
|
_subscriptions.push_back(observable.add_subscription(std_::forward<Lambda>(handler)));
|
||||||
return _subscriptions.size() - 1;
|
return _subscriptions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename EventType, typename Handler, typename Lambda>
|
template <typename EventType, typename Handler, typename Lambda>
|
||||||
|
@ -347,8 +366,14 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsubscribe(int index) {
|
void unsubscribe(int index) {
|
||||||
t_assert(index >= 0 && index < _subscriptions.size());
|
if (!index) return;
|
||||||
_subscriptions[index].destroy();
|
t_assert(index > 0 && index <= _subscriptions.size());
|
||||||
|
_subscriptions[index - 1].destroy();
|
||||||
|
if (index == _subscriptions.size()) {
|
||||||
|
while (index > 0 && !_subscriptions[--index]) {
|
||||||
|
_subscriptions.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Subscriber() {
|
~Subscriber() {
|
||||||
|
|
|
@ -139,6 +139,19 @@ struct enable_if<true, T> {
|
||||||
template <bool Test, typename T = void>
|
template <bool Test, typename T = void>
|
||||||
using enable_if_t = typename enable_if<Test, T>::type;
|
using enable_if_t = typename enable_if<Test, T>::type;
|
||||||
|
|
||||||
|
template <bool, typename First, typename Second>
|
||||||
|
struct conditional {
|
||||||
|
using type = Second;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename First, typename Second>
|
||||||
|
struct conditional<true, First, Second> {
|
||||||
|
using type = First;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool Test, typename First, typename Second>
|
||||||
|
using conditional_t = typename conditional<Test, First, Second>::type;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct add_const {
|
struct add_const {
|
||||||
using type = const T;
|
using type = const T;
|
||||||
|
|
102
Telegram/SourceFiles/core/type_traits.h
Normal file
102
Telegram/SourceFiles/core/type_traits.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/stl_subset.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct custom_is_fast_copy_type : public std_::false_type {
|
||||||
|
};
|
||||||
|
// To make your own type a fast copy type just write:
|
||||||
|
// template <>
|
||||||
|
// struct base::custom_is_fast_copy_type<MyTinyType> : public std_::true_type {
|
||||||
|
// };
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename ...Types>
|
||||||
|
struct type_list_contains;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct type_list_contains<T> : public std_::false_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Head, typename ...Types>
|
||||||
|
struct type_list_contains<T, Head, Types...> : public std_::integral_constant<bool, std_::is_same<Head, T>::value || type_list_contains<T, Types...>::value> {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_unsigned_int = type_list_contains<T, unsigned char, unsigned short int, unsigned int, unsigned long int>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_signed_int = type_list_contains<T, signed char, short int, int, long int>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_integral = std_::integral_constant<bool, is_std_unsigned_int<T>::value || is_std_signed_int<T>::value || type_list_contains<T, bool, char, wchar_t>::value>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_float = type_list_contains<T, float, double, long double>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_arith = std_::integral_constant<bool, is_std_integral<T>::value || is_std_float<T>::value>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_std_fundamental = std_::integral_constant<bool, is_std_arith<T>::value || std_::is_same<T, void>::value>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_pointer : public std_::false_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_pointer<T*> : public std_::true_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_member_pointer : public std_::false_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename C>
|
||||||
|
struct is_member_pointer<T C::*> : public std_::true_type {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using is_fast_copy_type = std_::integral_constant<bool, is_std_arith<T>::value || is_pointer<T>::value || is_member_pointer<T>::value || custom_is_fast_copy_type<T>::value>;
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct type_traits {
|
||||||
|
using is_std_unsigned_int = internal::is_std_unsigned_int<T>;
|
||||||
|
using is_std_signed_int = internal::is_std_signed_int<T>;
|
||||||
|
using is_std_integral = internal::is_std_integral<T>;
|
||||||
|
using is_std_float = internal::is_std_float<T>;
|
||||||
|
using is_std_arith = internal::is_std_arith<T>;
|
||||||
|
using is_std_fundamental = internal::is_std_fundamental<T>;
|
||||||
|
using is_pointer = internal::is_pointer<T>;
|
||||||
|
using is_member_pointer = internal::is_member_pointer<T>;
|
||||||
|
using is_fast_copy_type = internal::is_fast_copy_type<T>;
|
||||||
|
|
||||||
|
using parameter_type = std_::conditional_t<is_fast_copy_type::value, T, const T&>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace base
|
|
@ -55,6 +55,9 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p
|
||||||
_cancelSearchInPeer.hide();
|
_cancelSearchInPeer.hide();
|
||||||
|
|
||||||
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
||||||
|
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
itemRemoved(item);
|
||||||
|
});
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
@ -1900,10 +1903,6 @@ void DialogsWidget::onCancel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsWidget::itemRemoved(HistoryItem *item) {
|
|
||||||
_inner.itemRemoved(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogsWidget::updateNotifySettings(PeerData *peer) {
|
void DialogsWidget::updateNotifySettings(PeerData *peer) {
|
||||||
_inner.updateNotifySettings(peer);
|
_inner.updateNotifySettings(peer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ class DialogsInner : public SplittedWidget, public RPCSender, private base::Subs
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DialogsInner(QWidget *parent, MainWidget *main);
|
DialogsInner(QWidget *parent, MainWidget *main);
|
||||||
|
|
||||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
|
@ -119,7 +118,6 @@ public:
|
||||||
|
|
||||||
void onFilterUpdate(QString newFilter, bool force = false);
|
void onFilterUpdate(QString newFilter, bool force = false);
|
||||||
void onHashtagFilterUpdate(QStringRef newFilter);
|
void onHashtagFilterUpdate(QStringRef newFilter);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
|
||||||
PeerData *updateFromParentDrag(QPoint globalPos);
|
PeerData *updateFromParentDrag(QPoint globalPos);
|
||||||
|
|
||||||
|
@ -131,7 +129,6 @@ public:
|
||||||
~DialogsInner();
|
~DialogsInner();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onUpdateSelected(bool force = false);
|
void onUpdateSelected(bool force = false);
|
||||||
void onParentGeometryChanged();
|
void onParentGeometryChanged();
|
||||||
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
@ -152,7 +149,6 @@ public slots:
|
||||||
void peerUpdated(PeerData *peer);
|
void peerUpdated(PeerData *peer);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
||||||
void dialogMoved(int movedFrom, int movedTo);
|
void dialogMoved(int movedFrom, int movedTo);
|
||||||
void searchMessages();
|
void searchMessages();
|
||||||
|
@ -162,10 +158,10 @@ signals:
|
||||||
void refreshHashtags();
|
void refreshHashtags();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther);
|
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
|
|
||||||
int dialogsOffset() const;
|
int dialogsOffset() const;
|
||||||
int filteredOffset() const;
|
int filteredOffset() const;
|
||||||
|
@ -288,8 +284,6 @@ public:
|
||||||
void searchMessages(const QString &query, PeerData *inPeer = 0);
|
void searchMessages(const QString &query, PeerData *inPeer = 0);
|
||||||
void onSearchMore();
|
void onSearchMore();
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
|
||||||
void updateNotifySettings(PeerData *peer);
|
void updateNotifySettings(PeerData *peer);
|
||||||
|
|
||||||
void rpcClear() override {
|
void rpcClear() override {
|
||||||
|
|
|
@ -661,6 +661,8 @@ struct Data {
|
||||||
bool LocalPasscode = false;
|
bool LocalPasscode = false;
|
||||||
base::Observable<void> LocalPasscodeChanged;
|
base::Observable<void> LocalPasscodeChanged;
|
||||||
|
|
||||||
|
base::Observable<HistoryItem*> ItemRemoved;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -774,4 +776,6 @@ DefineVar(Global, int, AutoLock);
|
||||||
DefineVar(Global, bool, LocalPasscode);
|
DefineVar(Global, bool, LocalPasscode);
|
||||||
DefineRefVar(Global, base::Observable<void>, LocalPasscodeChanged);
|
DefineRefVar(Global, base::Observable<void>, LocalPasscodeChanged);
|
||||||
|
|
||||||
|
DefineRefVar(Global, base::Observable<HistoryItem*>, ItemRemoved);
|
||||||
|
|
||||||
} // namespace Global
|
} // namespace Global
|
||||||
|
|
|
@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/type_traits.h"
|
||||||
|
|
||||||
class LayerWidget;
|
class LayerWidget;
|
||||||
namespace base {
|
namespace base {
|
||||||
template <typename Type, typename>
|
template <typename Type, typename>
|
||||||
|
@ -170,6 +172,10 @@ inline bool IsTopCorner(ScreenCorner corner) {
|
||||||
|
|
||||||
} // namespace Notify
|
} // namespace Notify
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct base::custom_is_fast_copy_type<Notify::ChangeType> : public std_::true_type {
|
||||||
|
};
|
||||||
|
|
||||||
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
||||||
#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
#define DeclareRefVar(Type, Name) DeclareReadOnlyVar(Type, Name) \
|
||||||
Type &Ref##Name();
|
Type &Ref##Name();
|
||||||
|
@ -346,6 +352,8 @@ DeclareVar(int, AutoLock);
|
||||||
DeclareVar(bool, LocalPasscode);
|
DeclareVar(bool, LocalPasscode);
|
||||||
DeclareRefVar(base::Observable<void>, LocalPasscodeChanged);
|
DeclareRefVar(base::Observable<void>, LocalPasscodeChanged);
|
||||||
|
|
||||||
|
DeclareRefVar(base::Observable<HistoryItem*>, ItemRemoved);
|
||||||
|
|
||||||
} // namespace Global
|
} // namespace Global
|
||||||
|
|
||||||
namespace Adaptive {
|
namespace Adaptive {
|
||||||
|
|
|
@ -132,6 +132,9 @@ HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, His
|
||||||
notifyIsBotChanged();
|
notifyIsBotChanged();
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
itemRemoved(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages) {
|
void HistoryInner::messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages) {
|
||||||
|
@ -969,7 +972,11 @@ void HistoryInner::onDragExec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::itemRemoved(HistoryItem *item) {
|
void HistoryInner::itemRemoved(HistoryItem *item) {
|
||||||
SelectedItems::iterator i = _selected.find(item);
|
if (_history != item->history() && _migrated != item->history()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i = _selected.find(item);
|
||||||
if (i != _selected.cend()) {
|
if (i != _selected.cend()) {
|
||||||
_selected.erase(i);
|
_selected.erase(i);
|
||||||
_widget->updateTopBarSelection();
|
_widget->updateTopBarSelection();
|
||||||
|
@ -3130,7 +3137,10 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
|
|
||||||
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
|
connect(&_updateEditTimeLeftDisplay, SIGNAL(timeout()), this, SLOT(updateField()));
|
||||||
|
|
||||||
subscribe(Adaptive::Changed(), [this]() { update(); });
|
subscribe(Adaptive::Changed(), [this] { update(); });
|
||||||
|
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
itemRemoved(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::start() {
|
void HistoryWidget::start() {
|
||||||
|
@ -7044,7 +7054,6 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::itemRemoved(HistoryItem *item) {
|
void HistoryWidget::itemRemoved(HistoryItem *item) {
|
||||||
if (_list) _list->itemRemoved(item);
|
|
||||||
if (item == _replyEditMsg) {
|
if (item == _replyEditMsg) {
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
cancelEdit();
|
cancelEdit();
|
||||||
|
|
|
@ -46,11 +46,10 @@ class DragArea;
|
||||||
class EmojiPan;
|
class EmojiPan;
|
||||||
|
|
||||||
class HistoryWidget;
|
class HistoryWidget;
|
||||||
class HistoryInner : public TWidget, public AbstractTooltipShower {
|
class HistoryInner : public TWidget, public AbstractTooltipShower, private base::Subscriber {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history);
|
HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history);
|
||||||
|
|
||||||
void messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages);
|
void messagesReceived(PeerData *peer, const QVector<MTPMessage> &messages);
|
||||||
|
@ -92,8 +91,6 @@ public:
|
||||||
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
||||||
void selectItem(HistoryItem *item);
|
void selectItem(HistoryItem *item);
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
|
||||||
void updateBotInfo(bool recount = true);
|
void updateBotInfo(bool recount = true);
|
||||||
|
|
||||||
bool wasSelectedText() const;
|
bool wasSelectedText() const;
|
||||||
|
@ -126,7 +123,6 @@ protected:
|
||||||
bool focusNextPrevChild(bool next) override;
|
bool focusNextPrevChild(bool next) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onUpdateSelected();
|
void onUpdateSelected();
|
||||||
void onParentGeometryChanged();
|
void onParentGeometryChanged();
|
||||||
|
|
||||||
|
@ -146,11 +142,11 @@ public slots:
|
||||||
void onDragExec();
|
void onDragExec();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void onScrollDateCheck();
|
void onScrollDateCheck();
|
||||||
void onScrollDateHide();
|
void onScrollDateHide();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
|
|
||||||
void touchResetSpeed();
|
void touchResetSpeed();
|
||||||
void touchUpdateSpeed();
|
void touchUpdateSpeed();
|
||||||
|
@ -633,7 +629,6 @@ public:
|
||||||
void stopAnimActive();
|
void stopAnimActive();
|
||||||
|
|
||||||
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
void itemEdited(HistoryItem *item);
|
void itemEdited(HistoryItem *item);
|
||||||
|
|
||||||
void updateScrollColors();
|
void updateScrollColors();
|
||||||
|
@ -733,12 +728,10 @@ public:
|
||||||
~HistoryWidget();
|
~HistoryWidget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void cancelled();
|
void cancelled();
|
||||||
void historyShown(History *history, MsgId atMsgId);
|
void historyShown(History *history, MsgId atMsgId);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
void onReplyToMessage();
|
void onReplyToMessage();
|
||||||
void onEditMessage();
|
void onEditMessage();
|
||||||
|
@ -841,7 +834,6 @@ public slots:
|
||||||
void preloadHistoryIfNeeded();
|
void preloadHistoryIfNeeded();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method);
|
void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method);
|
||||||
void onMentionInsert(UserData *user);
|
void onMentionInsert(UserData *user);
|
||||||
void onInlineBotCancel();
|
void onInlineBotCancel();
|
||||||
|
@ -853,6 +845,7 @@ private slots:
|
||||||
void updateField();
|
void updateField();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
|
|
||||||
// Updates position of controls around the message field,
|
// Updates position of controls around the message field,
|
||||||
// like send button, emoji button and others.
|
// like send button, emoji button and others.
|
||||||
|
|
|
@ -73,6 +73,8 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window)
|
||||||
, _dialogs(this)
|
, _dialogs(this)
|
||||||
, _history(this)
|
, _history(this)
|
||||||
, _topBar(this)
|
, _topBar(this)
|
||||||
|
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
|
||||||
|
, _playerPanel(this, Media::Player::Panel::Layout::Full)
|
||||||
, _mediaType(this)
|
, _mediaType(this)
|
||||||
, _api(new ApiWrap(this)) {
|
, _api(new ApiWrap(this)) {
|
||||||
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
||||||
|
@ -120,6 +122,30 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window)
|
||||||
});
|
});
|
||||||
connect(&_cacheBackgroundTimer, SIGNAL(timeout()), this, SLOT(onCacheBackground()));
|
connect(&_cacheBackgroundTimer, SIGNAL(timeout()), this, SLOT(onCacheBackground()));
|
||||||
|
|
||||||
|
if (Media::Player::exists()) {
|
||||||
|
_playerPanel->setPinCallback([this] { switchToFixedPlayer(); });
|
||||||
|
subscribe(Media::Player::instance()->titleButtonOver(), [this](bool over) {
|
||||||
|
if (over) {
|
||||||
|
_playerPanel->showFromOther();
|
||||||
|
} else {
|
||||||
|
_playerPanel->hideFromOther();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
subscribe(Media::Player::instance()->playerWidgetOver(), [this](bool over) {
|
||||||
|
if (over) {
|
||||||
|
if (_playerPlaylist->isHidden()) {
|
||||||
|
auto position = mapFromGlobal(QCursor::pos()).x();
|
||||||
|
auto bestPosition = _playerPlaylist->bestPositionFor(position);
|
||||||
|
if (rtl()) bestPosition = position + 2 * (position - bestPosition) - _playerPlaylist->width();
|
||||||
|
updateMediaPlaylistPosition(bestPosition);
|
||||||
|
}
|
||||||
|
_playerPlaylist->showFromOther();
|
||||||
|
} else {
|
||||||
|
_playerPlaylist->hideFromOther();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); });
|
subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); });
|
||||||
|
|
||||||
_dialogs->show();
|
_dialogs->show();
|
||||||
|
@ -175,6 +201,7 @@ bool MainWidget::onForward(const PeerId &peer, ForwardWhatMessages what) {
|
||||||
_toForward.insert(item->id, item);
|
_toForward.insert(item->id, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateForwardingItemRemovedSubscription();
|
||||||
updateForwardingTexts();
|
updateForwardingTexts();
|
||||||
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
|
||||||
_history->onClearSelected();
|
_history->onClearSelected();
|
||||||
|
@ -277,11 +304,31 @@ void MainWidget::updateForwardingTexts() {
|
||||||
_toForwardNameVersion = version;
|
_toForwardNameVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::updateForwardingItemRemovedSubscription() {
|
||||||
|
if (_toForward.isEmpty()) {
|
||||||
|
unsubscribe(_forwardingItemRemovedSubscription);
|
||||||
|
_forwardingItemRemovedSubscription = 0;
|
||||||
|
} else if (!_forwardingItemRemovedSubscription) {
|
||||||
|
_forwardingItemRemovedSubscription = subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
auto i = _toForward.find(item->id);
|
||||||
|
if (i == _toForward.cend() || i.value() != item) {
|
||||||
|
i = _toForward.find(item->id - ServerMaxMsgId);
|
||||||
|
}
|
||||||
|
if (i != _toForward.cend() && i.value() == item) {
|
||||||
|
_toForward.erase(i);
|
||||||
|
updateForwardingItemRemovedSubscription();
|
||||||
|
updateForwardingTexts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::cancelForwarding() {
|
void MainWidget::cancelForwarding() {
|
||||||
if (_toForward.isEmpty()) return;
|
if (_toForward.isEmpty()) return;
|
||||||
|
|
||||||
_toForward.clear();
|
_toForward.clear();
|
||||||
_history->cancelForwarding();
|
_history->cancelForwarding();
|
||||||
|
updateForwardingItemRemovedSubscription();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::finishForwarding(History *history, bool silent) {
|
void MainWidget::finishForwarding(History *history, bool silent) {
|
||||||
|
@ -489,9 +536,8 @@ void MainWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
||||||
if (item->history()->lastMsg == item) {
|
if (item->history()->lastMsg == item) {
|
||||||
item->history()->updateChatListEntry();
|
item->history()->updateChatListEntry();
|
||||||
}
|
}
|
||||||
if (_playerPanel && !_playerPanel->isHidden()) {
|
_playerPlaylist->ui_repaintHistoryItem(item);
|
||||||
_playerPanel->ui_repaintHistoryItem(item);
|
_playerPanel->ui_repaintHistoryItem(item);
|
||||||
}
|
|
||||||
if (_overview) _overview->ui_repaintHistoryItem(item);
|
if (_overview) _overview->ui_repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1359,32 +1405,6 @@ void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) {
|
||||||
if (_overview) _overview->changingMsgId(row, newId);
|
if (_overview) _overview->changingMsgId(row, newId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::itemRemoved(HistoryItem *item) {
|
|
||||||
_dialogs->itemRemoved(item);
|
|
||||||
if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
|
|
||||||
_history->itemRemoved(item);
|
|
||||||
}
|
|
||||||
if (_overview && (_overview->peer() == item->history()->peer || (_overview->peer() && _overview->peer() == item->history()->peer->migrateTo()))) {
|
|
||||||
_overview->itemRemoved(item);
|
|
||||||
}
|
|
||||||
if (_playerPanel) {
|
|
||||||
_playerPanel->itemRemoved(item);
|
|
||||||
}
|
|
||||||
if (!_toForward.isEmpty()) {
|
|
||||||
SelectedItemSet::iterator i = _toForward.find(item->id);
|
|
||||||
if (i != _toForward.cend() && i.value() == item) {
|
|
||||||
_toForward.erase(i);
|
|
||||||
updateForwardingTexts();
|
|
||||||
} else {
|
|
||||||
i = _toForward.find(item->id - ServerMaxMsgId);
|
|
||||||
if (i != _toForward.cend() && i.value() == item) {
|
|
||||||
_toForward.erase(i);
|
|
||||||
updateForwardingTexts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::itemEdited(HistoryItem *item) {
|
void MainWidget::itemEdited(HistoryItem *item) {
|
||||||
if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
|
if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
|
||||||
_history->itemEdited(item);
|
_history->itemEdited(item);
|
||||||
|
@ -1558,7 +1578,7 @@ void MainWidget::handleAudioUpdate(const AudioMsgId &audioId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playing == audioId && audioId.type() == AudioMsgId::Type::Song) {
|
if (playing == audioId && audioId.type() == AudioMsgId::Type::Song) {
|
||||||
if (!_playerPanel && !_player && Media::Player::exists()) {
|
if (!_playerUsingPanel && !_player && Media::Player::exists()) {
|
||||||
createPlayer();
|
createPlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1574,19 +1594,20 @@ void MainWidget::handleAudioUpdate(const AudioMsgId &audioId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::switchToPanelPlayer() {
|
void MainWidget::switchToPanelPlayer() {
|
||||||
|
if (_playerUsingPanel) return;
|
||||||
|
_playerUsingPanel = true;
|
||||||
|
|
||||||
_player->slideUp();
|
_player->slideUp();
|
||||||
_playerVolume.destroyDelayed();
|
_playerVolume.destroyDelayed();
|
||||||
if (!_playerPanel) {
|
_playerPlaylist->hideIgnoringEnterEvents();
|
||||||
_playerPanel.create(this, Media::Player::Panel::Layout::Full);
|
|
||||||
_playerPanel->setPinCallback([this] { switchToFixedPlayer(); });
|
Media::Player::instance()->usePanelPlayer().notify(true, true);
|
||||||
updateMediaPlayerPosition();
|
|
||||||
orderWidgets();
|
|
||||||
Media::Player::instance()->createdNotifier().notify(Media::Player::PanelEvent(_playerPanel), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::switchToFixedPlayer() {
|
void MainWidget::switchToFixedPlayer() {
|
||||||
_playerPanel.destroyDelayed();
|
if (!_playerUsingPanel) return;
|
||||||
|
_playerUsingPanel = false;
|
||||||
|
|
||||||
if (!_player) {
|
if (!_player) {
|
||||||
createPlayer();
|
createPlayer();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1597,6 +1618,9 @@ void MainWidget::switchToFixedPlayer() {
|
||||||
updateMediaPlayerPosition();
|
updateMediaPlayerPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Media::Player::instance()->usePanelPlayer().notify(false, true);
|
||||||
|
_playerPanel->hideIgnoringEnterEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::createPlayer() {
|
void MainWidget::createPlayer() {
|
||||||
|
@ -1623,7 +1647,7 @@ void MainWidget::playerHeightUpdated() {
|
||||||
_playerHeight = playerHeight;
|
_playerHeight = playerHeight;
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
if (_playerPanel && !_playerHeight && _player->isHidden()) {
|
if (_playerUsingPanel && !_playerHeight && _player->isHidden()) {
|
||||||
_playerVolume.destroyDelayed();
|
_playerVolume.destroyDelayed();
|
||||||
_player.destroyDelayed();
|
_player.destroyDelayed();
|
||||||
}
|
}
|
||||||
|
@ -2319,6 +2343,15 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarS
|
||||||
if (playerVolumeVisible) {
|
if (playerVolumeVisible) {
|
||||||
_playerVolume->hide();
|
_playerVolume->hide();
|
||||||
}
|
}
|
||||||
|
auto playerPanelVisible = !_playerPanel->isHidden();
|
||||||
|
if (playerPanelVisible) {
|
||||||
|
_playerPanel->hide();
|
||||||
|
}
|
||||||
|
auto playerPlaylistVisible = !_playerPlaylist->isHidden();
|
||||||
|
if (playerPlaylistVisible) {
|
||||||
|
_playerPlaylist->hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (selectingPeer() && Adaptive::OneColumn()) {
|
if (selectingPeer() && Adaptive::OneColumn()) {
|
||||||
result.oldContentCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
result.oldContentCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
||||||
} else if (_wideSection) {
|
} else if (_wideSection) {
|
||||||
|
@ -2341,9 +2374,16 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarS
|
||||||
if (_overview) _overview->grabFinish();
|
if (_overview) _overview->grabFinish();
|
||||||
_history->grabFinish();
|
_history->grabFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerVolumeVisible) {
|
if (playerVolumeVisible) {
|
||||||
_playerVolume->show();
|
_playerVolume->show();
|
||||||
}
|
}
|
||||||
|
if (playerPanelVisible) {
|
||||||
|
_playerPanel->show();
|
||||||
|
}
|
||||||
|
if (playerPlaylistVisible) {
|
||||||
|
_playerPlaylist->show();
|
||||||
|
}
|
||||||
if (_player) {
|
if (_player) {
|
||||||
_player->showShadow();
|
_player->showShadow();
|
||||||
}
|
}
|
||||||
|
@ -2452,7 +2492,8 @@ void MainWidget::orderWidgets() {
|
||||||
}
|
}
|
||||||
_mediaType->raise();
|
_mediaType->raise();
|
||||||
_sideShadow->raise();
|
_sideShadow->raise();
|
||||||
if (_playerPanel) _playerPanel->raise();
|
_playerPlaylist->raise();
|
||||||
|
_playerPanel->raise();
|
||||||
if (_hider) _hider->raise();
|
if (_hider) _hider->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2473,6 +2514,15 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m
|
||||||
if (playerVolumeVisible) {
|
if (playerVolumeVisible) {
|
||||||
_playerVolume->hide();
|
_playerVolume->hide();
|
||||||
}
|
}
|
||||||
|
auto playerPanelVisible = !_playerPanel->isHidden();
|
||||||
|
if (playerPanelVisible) {
|
||||||
|
_playerPanel->hide();
|
||||||
|
}
|
||||||
|
auto playerPlaylistVisible = !_playerPlaylist->isHidden();
|
||||||
|
if (playerPlaylistVisible) {
|
||||||
|
_playerPlaylist->hide();
|
||||||
|
}
|
||||||
|
|
||||||
if (Adaptive::OneColumn()) {
|
if (Adaptive::OneColumn()) {
|
||||||
result = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
result = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
|
||||||
} else {
|
} else {
|
||||||
|
@ -2483,6 +2533,12 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m
|
||||||
if (playerVolumeVisible) {
|
if (playerVolumeVisible) {
|
||||||
_playerVolume->show();
|
_playerVolume->show();
|
||||||
}
|
}
|
||||||
|
if (playerPanelVisible) {
|
||||||
|
_playerPanel->show();
|
||||||
|
}
|
||||||
|
if (playerPlaylistVisible) {
|
||||||
|
_playerPlaylist->show();
|
||||||
|
}
|
||||||
if (_player) {
|
if (_player) {
|
||||||
_player->showShadow();
|
_player->showShadow();
|
||||||
}
|
}
|
||||||
|
@ -2762,20 +2818,34 @@ void MainWidget::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
if (_overview) _overview->setGeometry(_history->geometry());
|
if (_overview) _overview->setGeometry(_history->geometry());
|
||||||
updateMediaPlayerPosition();
|
updateMediaPlayerPosition();
|
||||||
|
updateMediaPlaylistPosition(_playerPlaylist->x());
|
||||||
_contentScrollAddToY = 0;
|
_contentScrollAddToY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updateMediaPlayerPosition() {
|
void MainWidget::updateMediaPlayerPosition() {
|
||||||
if (_playerPanel) {
|
_playerPanel->moveToRight(0, 0);
|
||||||
_playerPanel->moveToRight(0, 0);
|
if (_player && _playerVolume) {
|
||||||
}
|
|
||||||
if (_playerVolume && _player) {
|
|
||||||
auto relativePosition = _player->entity()->getPositionForVolumeWidget();
|
auto relativePosition = _player->entity()->getPositionForVolumeWidget();
|
||||||
auto playerMargins = _playerVolume->getMargin();
|
auto playerMargins = _playerVolume->getMargin();
|
||||||
_playerVolume->moveToLeft(_player->x() + relativePosition.x() - playerMargins.left(), _player->y() + relativePosition.y() - playerMargins.top());
|
_playerVolume->moveToLeft(_player->x() + relativePosition.x() - playerMargins.left(), _player->y() + relativePosition.y() - playerMargins.top());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::updateMediaPlaylistPosition(int x) {
|
||||||
|
if (_player) {
|
||||||
|
auto playlistLeft = x;
|
||||||
|
auto playlistWidth = _playerPlaylist->width();
|
||||||
|
auto playlistTop = _player->y() + _player->height();
|
||||||
|
auto rightEdge = width();
|
||||||
|
if (playlistLeft + playlistWidth > rightEdge) {
|
||||||
|
playlistLeft = rightEdge - playlistWidth;
|
||||||
|
} else if (playlistLeft < 0) {
|
||||||
|
playlistLeft = 0;
|
||||||
|
}
|
||||||
|
_playerPlaylist->move(playlistLeft, playlistTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int MainWidget::contentScrollAddToY() const {
|
int MainWidget::contentScrollAddToY() const {
|
||||||
return _contentScrollAddToY;
|
return _contentScrollAddToY;
|
||||||
}
|
}
|
||||||
|
@ -3529,7 +3599,8 @@ void MainWidget::onSelfParticipantUpdated(ChannelData *channel) {
|
||||||
|
|
||||||
bool MainWidget::contentOverlapped(const QRect &globalRect) {
|
bool MainWidget::contentOverlapped(const QRect &globalRect) {
|
||||||
return (_history->contentOverlapped(globalRect) ||
|
return (_history->contentOverlapped(globalRect) ||
|
||||||
(_playerPanel && _playerPanel->overlaps(globalRect)) ||
|
_playerPanel->overlaps(globalRect) ||
|
||||||
|
_playerPlaylist->overlaps(globalRect) ||
|
||||||
(_playerVolume && _playerVolume->overlaps(globalRect)) ||
|
(_playerVolume && _playerVolume->overlaps(globalRect)) ||
|
||||||
_mediaType->overlaps(globalRect));
|
_mediaType->overlaps(globalRect));
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,7 +307,6 @@ public:
|
||||||
void preloadOverviews(PeerData *peer);
|
void preloadOverviews(PeerData *peer);
|
||||||
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
|
||||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
void itemEdited(HistoryItem *item);
|
void itemEdited(HistoryItem *item);
|
||||||
|
|
||||||
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false);
|
||||||
|
@ -340,7 +339,6 @@ public:
|
||||||
|
|
||||||
bool hasForwardingItems();
|
bool hasForwardingItems();
|
||||||
void fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor, ImagePtr &preview);
|
void fillForwardingInfo(Text *&from, Text *&text, bool &serviceColor, ImagePtr &preview);
|
||||||
void updateForwardingTexts();
|
|
||||||
void cancelForwarding();
|
void cancelForwarding();
|
||||||
void finishForwarding(History *hist, bool silent); // send them
|
void finishForwarding(History *hist, bool silent); // send them
|
||||||
|
|
||||||
|
@ -484,8 +482,12 @@ private:
|
||||||
void updateAdaptiveLayout();
|
void updateAdaptiveLayout();
|
||||||
void handleAudioUpdate(const AudioMsgId &audioId);
|
void handleAudioUpdate(const AudioMsgId &audioId);
|
||||||
void updateMediaPlayerPosition();
|
void updateMediaPlayerPosition();
|
||||||
|
void updateMediaPlaylistPosition(int x);
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
|
||||||
|
void updateForwardingTexts();
|
||||||
|
void updateForwardingItemRemovedSubscription();
|
||||||
|
|
||||||
void createPlayer();
|
void createPlayer();
|
||||||
void switchToPanelPlayer();
|
void switchToPanelPlayer();
|
||||||
void switchToFixedPlayer();
|
void switchToFixedPlayer();
|
||||||
|
@ -520,6 +522,7 @@ private:
|
||||||
SelectedItemSet _toForward;
|
SelectedItemSet _toForward;
|
||||||
Text _toForwardFrom, _toForwardText;
|
Text _toForwardFrom, _toForwardText;
|
||||||
int32 _toForwardNameVersion = 0;
|
int32 _toForwardNameVersion = 0;
|
||||||
|
int _forwardingItemRemovedSubscription = 0;
|
||||||
|
|
||||||
OrderedSet<WebPageId> _webPagesUpdated;
|
OrderedSet<WebPageId> _webPagesUpdated;
|
||||||
OrderedSet<GameId> _gamesUpdated;
|
OrderedSet<GameId> _gamesUpdated;
|
||||||
|
@ -589,9 +592,13 @@ private:
|
||||||
ChildWidget<Window::SectionWidget> _wideSection = { nullptr };
|
ChildWidget<Window::SectionWidget> _wideSection = { nullptr };
|
||||||
ChildWidget<OverviewWidget> _overview = { nullptr };
|
ChildWidget<OverviewWidget> _overview = { nullptr };
|
||||||
ChildWidget<Window::TopBarWidget> _topBar;
|
ChildWidget<Window::TopBarWidget> _topBar;
|
||||||
|
|
||||||
ChildWidget<Window::PlayerWrapWidget> _player = { nullptr };
|
ChildWidget<Window::PlayerWrapWidget> _player = { nullptr };
|
||||||
ChildWidget<Media::Player::VolumeWidget> _playerVolume = { nullptr };
|
ChildWidget<Media::Player::VolumeWidget> _playerVolume = { nullptr };
|
||||||
ChildWidget<Media::Player::Panel> _playerPanel = { nullptr };
|
ChildWidget<Media::Player::Panel> _playerPlaylist;
|
||||||
|
ChildWidget<Media::Player::Panel> _playerPanel;
|
||||||
|
bool _playerUsingPanel = false;
|
||||||
|
|
||||||
ConfirmBox *_forwardConfirm = nullptr; // for single column layout
|
ConfirmBox *_forwardConfirm = nullptr; // for single column layout
|
||||||
ChildWidget<HistoryHider> _hider = { nullptr };
|
ChildWidget<HistoryHider> _hider = { nullptr };
|
||||||
std_::vector_of_moveable<std_::unique_ptr<StackItem>> _stack;
|
std_::vector_of_moveable<std_::unique_ptr<StackItem>> _stack;
|
||||||
|
|
|
@ -90,7 +90,7 @@ MainWindow::MainWindow() {
|
||||||
iconbig32 = iconbig256.scaledToWidth(32, Qt::SmoothTransformation);
|
iconbig32 = iconbig256.scaledToWidth(32, Qt::SmoothTransformation);
|
||||||
iconbig64 = iconbig256.scaledToWidth(64, Qt::SmoothTransformation);
|
iconbig64 = iconbig256.scaledToWidth(64, Qt::SmoothTransformation);
|
||||||
|
|
||||||
subscribe(Global::RefNotifySettingsChanged(), [this](const Notify::ChangeType &type) {
|
subscribe(Global::RefNotifySettingsChanged(), [this](Notify::ChangeType type) {
|
||||||
if (type == Notify::ChangeType::DesktopEnabled) {
|
if (type == Notify::ChangeType::DesktopEnabled) {
|
||||||
updateTrayMenu();
|
updateTrayMenu();
|
||||||
notifyClear();
|
notifyClear();
|
||||||
|
|
|
@ -239,13 +239,20 @@ mediaPlayerScroll: flatScroll(solidScroll) {
|
||||||
}
|
}
|
||||||
mediaPlayerListHeightMax: 280px;
|
mediaPlayerListHeightMax: 280px;
|
||||||
mediaPlayerListMarginBottom: 10px;
|
mediaPlayerListMarginBottom: 10px;
|
||||||
mediaPlayerScrollShadow: icon {{ "player_playlist_shadow", #000000 }};
|
mediaPlayerScrollShadow: icon {{ "playlist_shadow", #000000 }};
|
||||||
|
|
||||||
mediaPlayerListMarginTop: 8px;
|
mediaPlayerListMarginTop: 8px;
|
||||||
|
mediaPlayerListIconFg: #ffffff;
|
||||||
mediaPlayerFileLayout: OverviewFileLayout(overviewFileLayout) {
|
mediaPlayerFileLayout: OverviewFileLayout(overviewFileLayout) {
|
||||||
maxWidth: 344px;
|
maxWidth: 344px;
|
||||||
songPadding: margins(17px, 7px, 10px, 6px);
|
songPadding: margins(17px, 7px, 10px, 6px);
|
||||||
songThumbSize: 36px;
|
songThumbSize: 36px;
|
||||||
songNameTop: 7px;
|
songNameTop: 7px;
|
||||||
songStatusTop: 25px;
|
songStatusTop: 25px;
|
||||||
|
songIconBg: mediaPlayerActiveFg;
|
||||||
|
songOverBg: mediaPlayerActiveFg;
|
||||||
|
songPause: icon {{ "playlist_pause", mediaPlayerListIconFg }};
|
||||||
|
songPlay: icon {{ "playlist_play", mediaPlayerListIconFg }};
|
||||||
|
songCancel: icon {{ "playlist_cancel", mediaPlayerListIconFg }};
|
||||||
|
songDownload: icon {{ "playlist_download", mediaPlayerListIconFg }};
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _pinPlayer(this, st::mediaPlayerPanelPinButton)
|
, _pinPlayer(this, st::mediaPlayerPanelPinButton)
|
||||||
, _repeatTrack(this, st::mediaPlayerRepeatButton) {
|
, _repeatTrack(this, st::mediaPlayerRepeatButton) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
resize(width(), st::mediaPlayerCoverHeight);
|
||||||
|
|
||||||
_playback->setChangeProgressCallback([this](float64 value) {
|
_playback->setChangeProgressCallback([this](float64 value) {
|
||||||
handleSeekProgress(value);
|
handleSeekProgress(value);
|
||||||
|
@ -315,12 +316,14 @@ void CoverWidget::handlePlaylistUpdate() {
|
||||||
void CoverWidget::createPrevNextButtons() {
|
void CoverWidget::createPrevNextButtons() {
|
||||||
if (!_previousTrack) {
|
if (!_previousTrack) {
|
||||||
_previousTrack.create(this, st::mediaPlayerPanelPreviousButton);
|
_previousTrack.create(this, st::mediaPlayerPanelPreviousButton);
|
||||||
_nextTrack.create(this, st::mediaPlayerPanelNextButton);
|
_previousTrack->show();
|
||||||
_previousTrack->setClickedCallback([this]() {
|
_previousTrack->setClickedCallback([this]() {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
instance()->previous();
|
instance()->previous();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_nextTrack.create(this, st::mediaPlayerPanelNextButton);
|
||||||
|
_nextTrack->show();
|
||||||
_nextTrack->setClickedCallback([this]() {
|
_nextTrack->setClickedCallback([this]() {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
instance()->next();
|
instance()->next();
|
||||||
|
|
|
@ -40,12 +40,6 @@ bool exists();
|
||||||
class Instance;
|
class Instance;
|
||||||
Instance *instance();
|
Instance *instance();
|
||||||
|
|
||||||
class Panel;
|
|
||||||
struct PanelEvent {
|
|
||||||
explicit PanelEvent(Panel *panel) : panel(panel) {
|
|
||||||
}
|
|
||||||
Panel *panel;
|
|
||||||
};
|
|
||||||
struct UpdatedEvent {
|
struct UpdatedEvent {
|
||||||
UpdatedEvent(const AudioMsgId *audioId, const AudioPlaybackState *playbackState) : audioId(audioId), playbackState(playbackState) {
|
UpdatedEvent(const AudioMsgId *audioId, const AudioPlaybackState *playbackState) : audioId(audioId), playbackState(playbackState) {
|
||||||
}
|
}
|
||||||
|
@ -87,11 +81,14 @@ public:
|
||||||
return _playlist;
|
return _playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
base::Observable<PanelEvent> &createdNotifier() {
|
base::Observable<bool> &usePanelPlayer() {
|
||||||
return _createdNotifier;
|
return _usePanelPlayer;
|
||||||
}
|
}
|
||||||
base::Observable<PanelEvent> &destroyedNotifier() {
|
base::Observable<bool> &titleButtonOver() {
|
||||||
return _destroyedNotifier;
|
return _titleButtonOver;
|
||||||
|
}
|
||||||
|
base::Observable<bool> &playerWidgetOver() {
|
||||||
|
return _playerWidgetOver;
|
||||||
}
|
}
|
||||||
base::Observable<UpdatedEvent> &updatedNotifier() {
|
base::Observable<UpdatedEvent> &updatedNotifier() {
|
||||||
return _updatedNotifier;
|
return _updatedNotifier;
|
||||||
|
@ -133,8 +130,9 @@ private:
|
||||||
QList<FullMsgId> _playlist;
|
QList<FullMsgId> _playlist;
|
||||||
bool _isPlaying = false;
|
bool _isPlaying = false;
|
||||||
|
|
||||||
base::Observable<PanelEvent> _createdNotifier;
|
base::Observable<bool> _usePanelPlayer;
|
||||||
base::Observable<PanelEvent> _destroyedNotifier;
|
base::Observable<bool> _titleButtonOver;
|
||||||
|
base::Observable<bool> _playerWidgetOver;
|
||||||
base::Observable<UpdatedEvent> _updatedNotifier;
|
base::Observable<UpdatedEvent> _updatedNotifier;
|
||||||
base::Observable<void> _playlistChangedNotifier;
|
base::Observable<void> _playlistChangedNotifier;
|
||||||
base::Observable<void> _songChangedNotifier;
|
base::Observable<void> _songChangedNotifier;
|
||||||
|
|
|
@ -34,6 +34,9 @@ ListWidget::ListWidget() {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
subscribe(instance()->playlistChangedNotifier(), [this] { playlistUpdated(); });
|
subscribe(instance()->playlistChangedNotifier(), [this] { playlistUpdated(); });
|
||||||
}
|
}
|
||||||
|
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
itemRemoved(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ListWidget::~ListWidget() {
|
ListWidget::~ListWidget() {
|
||||||
|
@ -143,10 +146,32 @@ void ListWidget::itemRemoved(HistoryItem *item) {
|
||||||
if (layoutIt != _layouts.cend()) {
|
if (layoutIt != _layouts.cend()) {
|
||||||
auto layout = layoutIt.value();
|
auto layout = layoutIt.value();
|
||||||
_layouts.erase(layoutIt);
|
_layouts.erase(layoutIt);
|
||||||
|
|
||||||
|
for (int i = 0, count = _list.size(); i != count; ++i) {
|
||||||
|
if (_list[i] == layout) {
|
||||||
|
_list.removeAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
delete layout;
|
delete layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect ListWidget::getCurrentTrackGeometry() const {
|
||||||
|
if (exists()) {
|
||||||
|
auto top = marginTop();
|
||||||
|
auto current = instance()->current();
|
||||||
|
for_const (auto layout, _list) {
|
||||||
|
auto layoutHeight = layout->height();
|
||||||
|
if (layout->getItem()->fullId() == current.contextId()) {
|
||||||
|
return QRect(0, top, width(), layoutHeight);
|
||||||
|
}
|
||||||
|
top += layoutHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QRect(0, height(), width(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
int ListWidget::resizeGetHeight(int newWidth) {
|
int ListWidget::resizeGetHeight(int newWidth) {
|
||||||
auto result = 0;
|
auto result = 0;
|
||||||
for_const (auto layout, _list) {
|
for_const (auto layout, _list) {
|
||||||
|
|
|
@ -34,7 +34,8 @@ public:
|
||||||
ListWidget();
|
ListWidget();
|
||||||
|
|
||||||
void ui_repaintHistoryItem(const HistoryItem *item);
|
void ui_repaintHistoryItem(const HistoryItem *item);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
QRect getCurrentTrackGeometry() const;
|
||||||
|
|
||||||
~ListWidget();
|
~ListWidget();
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ protected:
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
int marginTop() const;
|
int marginTop() const;
|
||||||
void repaintItem(const HistoryItem *item);
|
void repaintItem(const HistoryItem *item);
|
||||||
void playlistUpdated();
|
void playlistUpdated();
|
||||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2016 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_list.h"
|
#include "media/player/media_player_list.h"
|
||||||
#include "media/player/media_player_instance.h"
|
#include "media/player/media_player_instance.h"
|
||||||
|
#include "styles/style_overview.h"
|
||||||
#include "styles/style_media_player.h"
|
#include "styles/style_media_player.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
@ -32,36 +33,25 @@ namespace Media {
|
||||||
namespace Player {
|
namespace Player {
|
||||||
|
|
||||||
Panel::Panel(QWidget *parent, Layout layout) : TWidget(parent)
|
Panel::Panel(QWidget *parent, Layout layout) : TWidget(parent)
|
||||||
|
, _layout(layout)
|
||||||
, _shadow(st::defaultInnerDropdown.shadow)
|
, _shadow(st::defaultInnerDropdown.shadow)
|
||||||
, _scroll(this, st::mediaPlayerScroll)
|
, _scroll(this, st::mediaPlayerScroll) {
|
||||||
, _scrollShadow(this, st::mediaPlayerScrollShadow) {
|
|
||||||
if (layout == Layout::Full) {
|
|
||||||
_cover.create(this);
|
|
||||||
}
|
|
||||||
_hideTimer.setSingleShot(true);
|
_hideTimer.setSingleShot(true);
|
||||||
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideStart()));
|
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideStart()));
|
||||||
|
|
||||||
auto list = std_::make_unique<ListWidget>();
|
|
||||||
connect(list.get(), SIGNAL(heightUpdated()), this, SLOT(onListHeightUpdated()));
|
|
||||||
_scroll->setOwnedWidget(list.release());
|
|
||||||
|
|
||||||
_showTimer.setSingleShot(true);
|
_showTimer.setSingleShot(true);
|
||||||
connect(&_showTimer, SIGNAL(timeout()), this, SLOT(onShowStart()));
|
connect(&_showTimer, SIGNAL(timeout()), this, SLOT(onShowStart()));
|
||||||
|
|
||||||
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
|
||||||
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
|
|
||||||
}
|
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
onListHeightUpdated();
|
updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Panel::overlaps(const QRect &globalRect) {
|
bool Panel::overlaps(const QRect &globalRect) {
|
||||||
if (isHidden() || _a_appearance.animating()) return false;
|
if (isHidden() || _a_appearance.animating()) return false;
|
||||||
|
|
||||||
auto marginLeft = rtl() ? 0 : contentLeft();
|
auto marginLeft = rtl() ? contentRight() : contentLeft();
|
||||||
auto marginRight = rtl() ? contentLeft() : 0;
|
auto marginRight = rtl() ? contentLeft() : contentRight();
|
||||||
return rect().marginsRemoved(QMargins(marginLeft, 0, marginRight, st::mediaPlayerPanelMarginBottom)).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::onWindowActiveChanged() {
|
||||||
|
@ -71,16 +61,28 @@ void Panel::onWindowActiveChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::resizeEvent(QResizeEvent *e) {
|
void Panel::resizeEvent(QResizeEvent *e) {
|
||||||
auto width = contentWidth();
|
updateControlsGeometry();
|
||||||
_cover->resize(width, st::mediaPlayerCoverHeight);
|
}
|
||||||
_cover->moveToRight(0, 0);
|
|
||||||
|
|
||||||
auto scrollTop = _cover->height();
|
void Panel::onListHeightUpdated() {
|
||||||
auto scrollHeight = qMax(contentHeight() - scrollTop - st::mediaPlayerListMarginBottom, 0);
|
updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::updateControlsGeometry() {
|
||||||
|
auto scrollTop = contentTop();
|
||||||
|
auto width = contentWidth();
|
||||||
|
if (_cover) {
|
||||||
|
_cover->resizeToWidth(width);
|
||||||
|
_cover->moveToRight(contentRight(), scrollTop);
|
||||||
|
scrollTop += _cover->height();
|
||||||
|
if (_scrollShadow) {
|
||||||
|
_scrollShadow->resizeToWidth(width);
|
||||||
|
_scrollShadow->moveToRight(contentRight(), scrollTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto scrollHeight = qMax(height() - scrollTop - contentBottom() - scrollMarginBottom(), 0);
|
||||||
if (scrollHeight > 0) {
|
if (scrollHeight > 0) {
|
||||||
_scroll->setGeometryToRight(0, scrollTop, width, scrollHeight);
|
_scroll->setGeometryToRight(contentRight(), scrollTop, width, scrollHeight);
|
||||||
_scrollShadow->resizeToWidth(width);
|
|
||||||
_scrollShadow->moveToRight(0, scrollTop);
|
|
||||||
}
|
}
|
||||||
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
|
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
|
||||||
widget->resizeToWidth(width);
|
widget->resizeToWidth(width);
|
||||||
|
@ -88,19 +90,28 @@ void Panel::resizeEvent(QResizeEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onListHeightUpdated() {
|
|
||||||
updateSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Panel::ui_repaintHistoryItem(const HistoryItem *item) {
|
void Panel::ui_repaintHistoryItem(const HistoryItem *item) {
|
||||||
if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||||
list->ui_repaintHistoryItem(item);
|
list->ui_repaintHistoryItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::itemRemoved(HistoryItem *item) {
|
int Panel::bestPositionFor(int left) const {
|
||||||
|
left -= contentLeft();
|
||||||
|
left -= st::mediaPlayerFileLayout.songPadding.left();
|
||||||
|
left -= st::mediaPlayerFileLayout.songThumbSize / 2;
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::scrollPlaylistToCurrentTrack() {
|
||||||
if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
if (auto list = static_cast<ListWidget*>(_scroll->widget())) {
|
||||||
list->itemRemoved(item);
|
auto rect = list->getCurrentTrackGeometry();
|
||||||
|
auto top = _scroll->scrollTop(), bottom = top + _scroll->height();
|
||||||
|
_scroll->scrollToY(rect.y());
|
||||||
|
//if (top > rect.y()) {
|
||||||
|
//} else if (bottom < rect.y() + rect.height()) {
|
||||||
|
// _scroll->scrollToY(rect.y() + rect.height() - _scroll->height());
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,17 +124,23 @@ void Panel::onScroll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::updateSize() {
|
void Panel::updateSize() {
|
||||||
|
auto width = contentLeft() + st::mediaPlayerPanelWidth + contentRight();
|
||||||
|
auto height = contentTop();
|
||||||
|
if (_cover) {
|
||||||
|
height += _cover->height();
|
||||||
|
}
|
||||||
auto listHeight = 0;
|
auto listHeight = 0;
|
||||||
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
|
if (auto widget = static_cast<ScrolledWidget*>(_scroll->widget())) {
|
||||||
listHeight = widget->height();
|
listHeight = widget->height();
|
||||||
}
|
}
|
||||||
auto scrollVisible = (listHeight > 0);
|
auto scrollVisible = (listHeight > 0);
|
||||||
auto scrollHeight = scrollVisible ? (qMin(listHeight, st::mediaPlayerListHeightMax) + st::mediaPlayerListMarginBottom) : 0;
|
auto scrollHeight = scrollVisible ? (qMin(listHeight, st::mediaPlayerListHeightMax) + st::mediaPlayerListMarginBottom) : 0;
|
||||||
auto width = contentLeft() + st::mediaPlayerPanelWidth;
|
height += scrollHeight + contentBottom();
|
||||||
auto height = st::mediaPlayerCoverHeight + scrollHeight + st::mediaPlayerPanelMarginBottom;
|
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
_scroll->setVisible(scrollVisible);
|
_scroll->setVisible(scrollVisible);
|
||||||
_scrollShadow->setVisible(scrollVisible);
|
if (_scrollShadow) {
|
||||||
|
_scrollShadow->setVisible(scrollVisible);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::paintEvent(QPaintEvent *e) {
|
void Panel::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -146,13 +163,19 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw shadow
|
// draw shadow
|
||||||
auto shadowedRect = myrtlrect(contentLeft(), 0, contentWidth(), height() - st::mediaPlayerPanelMarginBottom);
|
using Side = Ui::RectShadow::Side;
|
||||||
auto shadowedSides = (rtl() ? Ui::RectShadow::Side::Right : Ui::RectShadow::Side::Left) | Ui::RectShadow::Side::Bottom;
|
auto shadowedRect = myrtlrect(contentLeft(), contentTop(), contentWidth(), contentHeight());
|
||||||
|
auto shadowedSides = (rtl() ? Side::Right : Side::Left) | Side::Bottom;
|
||||||
|
if (_layout != Layout::Full) {
|
||||||
|
shadowedSides |= (rtl() ? Side::Left : Side::Right) | Side::Top;
|
||||||
|
}
|
||||||
_shadow.paint(p, shadowedRect, st::defaultInnerDropdown.shadowShift, shadowedSides);
|
_shadow.paint(p, shadowedRect, st::defaultInnerDropdown.shadowShift, shadowedSides);
|
||||||
p.fillRect(shadowedRect, st::windowBg);
|
p.fillRect(shadowedRect, st::windowBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::enterEvent(QEvent *e) {
|
void Panel::enterEvent(QEvent *e) {
|
||||||
|
if (_ignoringEnterEvents) return;
|
||||||
|
|
||||||
_hideTimer.stop();
|
_hideTimer.stop();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onShowStart();
|
onShowStart();
|
||||||
|
@ -172,7 +195,7 @@ void Panel::leaveEvent(QEvent *e) {
|
||||||
return TWidget::leaveEvent(e);
|
return TWidget::leaveEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::otherEnter() {
|
void Panel::showFromOther() {
|
||||||
_hideTimer.stop();
|
_hideTimer.stop();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onShowStart();
|
onShowStart();
|
||||||
|
@ -181,7 +204,7 @@ void Panel::otherEnter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::otherLeave() {
|
void Panel::hideFromOther() {
|
||||||
_showTimer.stop();
|
_showTimer.stop();
|
||||||
if (_a_appearance.animating(getms())) {
|
if (_a_appearance.animating(getms())) {
|
||||||
onHideStart();
|
onHideStart();
|
||||||
|
@ -190,20 +213,56 @@ void Panel::otherLeave() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::setPinCallback(PinCallback &&callback) {
|
void Panel::ensureCreated() {
|
||||||
if (_cover) {
|
if (_scroll->widget()) return;
|
||||||
_cover->setPinCallback(std_::move(callback));
|
|
||||||
|
if (_layout == Layout::Full) {
|
||||||
|
_cover.create(this);
|
||||||
|
setPinCallback(std_::move(_pinCallback));
|
||||||
|
|
||||||
|
_scrollShadow.create(this, st::mediaPlayerScrollShadow);
|
||||||
|
}
|
||||||
|
auto list = std_::make_unique<ListWidget>();
|
||||||
|
connect(list.get(), SIGNAL(heightUpdated()), this, SLOT(onListHeightUpdated()));
|
||||||
|
_scroll->setOwnedWidget(list.release());
|
||||||
|
|
||||||
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
|
if (auto window = App::wnd()) {
|
||||||
|
connect(window->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSize();
|
||||||
|
updateControlsGeometry();
|
||||||
|
_ignoringEnterEvents = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panel::performDestroy() {
|
||||||
|
if (!_scroll->widget()) return;
|
||||||
|
|
||||||
|
_cover.destroy();
|
||||||
|
auto list = _scroll->takeWidget();
|
||||||
|
list->hide();
|
||||||
|
list->deleteLater();
|
||||||
|
|
||||||
|
if (cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
|
if (auto window = App::wnd()) {
|
||||||
|
disconnect(window->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWindowActiveChanged()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel::~Panel() {
|
void Panel::setPinCallback(PinCallback &&callback) {
|
||||||
if (exists()) {
|
_pinCallback = std_::move(callback);
|
||||||
instance()->destroyedNotifier().notify(Media::Player::PanelEvent(this), true);
|
if (_cover) {
|
||||||
|
_cover->setPinCallback(PinCallback(_pinCallback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::onShowStart() {
|
void Panel::onShowStart() {
|
||||||
|
ensureCreated();
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
|
scrollPlaylistToCurrentTrack();
|
||||||
show();
|
show();
|
||||||
} else if (!_hiding) {
|
} else if (!_hiding) {
|
||||||
return;
|
return;
|
||||||
|
@ -212,8 +271,17 @@ void Panel::onShowStart() {
|
||||||
startAnimation();
|
startAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panel::hideIgnoringEnterEvents() {
|
||||||
|
_ignoringEnterEvents = true;
|
||||||
|
if (isHidden()) {
|
||||||
|
hidingFinished();
|
||||||
|
} else {
|
||||||
|
onHideStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::onHideStart() {
|
void Panel::onHideStart() {
|
||||||
if (_hiding) return;
|
if (_hiding || isHidden()) return;
|
||||||
|
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
startAnimation();
|
startAnimation();
|
||||||
|
@ -242,23 +310,27 @@ void Panel::appearanceCallback() {
|
||||||
void Panel::hidingFinished() {
|
void Panel::hidingFinished() {
|
||||||
hide();
|
hide();
|
||||||
_cache = QPixmap();
|
_cache = QPixmap();
|
||||||
|
performDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Panel::contentLeft() const {
|
int Panel::contentLeft() const {
|
||||||
return st::mediaPlayerPanelMarginLeft;
|
return st::mediaPlayerPanelMarginLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Panel::contentHeight() const {
|
int Panel::contentTop() const {
|
||||||
return height() - st::mediaPlayerPanelMarginBottom;
|
return (_layout == Layout::Full) ? 0 : st::mediaPlayerPanelMarginLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Panel::eventFilter(QObject *obj, QEvent *e) {
|
int Panel::contentRight() const {
|
||||||
if (e->type() == QEvent::Enter) {
|
return (_layout == Layout::Full) ? 0 : st::mediaPlayerPanelMarginLeft;
|
||||||
otherEnter();
|
}
|
||||||
} else if (e->type() == QEvent::Leave) {
|
|
||||||
otherLeave();
|
int Panel::contentBottom() const {
|
||||||
}
|
return st::mediaPlayerPanelMarginBottom;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
int Panel::scrollMarginBottom() const {
|
||||||
|
return st::mediaPlayerPanelMarginBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Player {
|
||||||
class CoverWidget;
|
class CoverWidget;
|
||||||
class ListWidget;
|
class ListWidget;
|
||||||
|
|
||||||
class Panel : public TWidget, private base::Subscriber {
|
class Panel : public TWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -44,19 +44,19 @@ public:
|
||||||
};
|
};
|
||||||
Panel(QWidget *parent, Layout layout);
|
Panel(QWidget *parent, Layout layout);
|
||||||
|
|
||||||
void setLayout(Layout layout);
|
|
||||||
bool overlaps(const QRect &globalRect);
|
bool overlaps(const QRect &globalRect);
|
||||||
|
|
||||||
void otherEnter();
|
void hideIgnoringEnterEvents();
|
||||||
void otherLeave();
|
|
||||||
|
|
||||||
using PinCallback = base::lambda_unique<void()>;
|
void showFromOther();
|
||||||
|
void hideFromOther();
|
||||||
|
|
||||||
|
using PinCallback = base::lambda_wrap<void()>;
|
||||||
void setPinCallback(PinCallback &&callback);
|
void setPinCallback(PinCallback &&callback);
|
||||||
|
|
||||||
void ui_repaintHistoryItem(const HistoryItem *item);
|
void ui_repaintHistoryItem(const HistoryItem *item);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
|
||||||
~Panel();
|
int bestPositionFor(int left) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
@ -64,40 +64,53 @@ protected:
|
||||||
void enterEvent(QEvent *e) override;
|
void enterEvent(QEvent *e) override;
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
|
|
||||||
bool eventFilter(QObject *obj, QEvent *e) override;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onShowStart();
|
void onShowStart();
|
||||||
void onHideStart();
|
void onHideStart();
|
||||||
|
|
||||||
void onScroll();
|
void onScroll();
|
||||||
|
|
||||||
void onListHeightUpdated();
|
void onListHeightUpdated();
|
||||||
|
|
||||||
void onWindowActiveChanged();
|
void onWindowActiveChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ensureCreated();
|
||||||
|
void performDestroy();
|
||||||
|
|
||||||
|
void updateControlsGeometry();
|
||||||
|
|
||||||
void updateSize();
|
void updateSize();
|
||||||
void appearanceCallback();
|
void appearanceCallback();
|
||||||
void hidingFinished();
|
void hidingFinished();
|
||||||
int contentLeft() const;
|
int contentLeft() const;
|
||||||
|
int contentTop() const;
|
||||||
|
int contentRight() const;
|
||||||
|
int contentBottom() const;
|
||||||
|
int scrollMarginBottom() const;
|
||||||
int contentWidth() const {
|
int contentWidth() const {
|
||||||
return width() - contentLeft();
|
return width() - contentLeft() - contentRight();
|
||||||
|
}
|
||||||
|
int contentHeight() const {
|
||||||
|
return height() - contentTop() - contentBottom();;
|
||||||
}
|
}
|
||||||
int contentHeight() const;
|
|
||||||
|
|
||||||
void startAnimation();
|
void startAnimation();
|
||||||
|
void scrollPlaylistToCurrentTrack();
|
||||||
|
|
||||||
|
Layout _layout;
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
|
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
FloatAnimation _a_appearance;
|
FloatAnimation _a_appearance;
|
||||||
|
|
||||||
|
bool _ignoringEnterEvents = false;
|
||||||
|
|
||||||
QTimer _hideTimer, _showTimer;
|
QTimer _hideTimer, _showTimer;
|
||||||
|
|
||||||
Ui::RectShadow _shadow;
|
Ui::RectShadow _shadow;
|
||||||
|
PinCallback _pinCallback;
|
||||||
ChildWidget<CoverWidget> _cover = { nullptr };
|
ChildWidget<CoverWidget> _cover = { nullptr };
|
||||||
ChildWidget<ScrollArea> _scroll;
|
ChildWidget<ScrollArea> _scroll;
|
||||||
ChildWidget<Ui::GradientShadow> _scrollShadow;
|
ChildWidget<Ui::GradientShadow> _scrollShadow = { nullptr };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,20 @@ void TitleButton::paintIcon(Painter &p) {
|
||||||
_layout->paint(p, icon);
|
_layout->paint(p, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TitleButton::enterEvent(QEvent *e) {
|
||||||
|
if (exists()) {
|
||||||
|
instance()->titleButtonOver().notify(true, true);
|
||||||
|
}
|
||||||
|
return Button::enterEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleButton::leaveEvent(QEvent *e) {
|
||||||
|
if (exists()) {
|
||||||
|
instance()->titleButtonOver().notify(false, true);
|
||||||
|
}
|
||||||
|
return Button::leaveEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
TitleButton::~TitleButton() = default;
|
TitleButton::~TitleButton() = default;
|
||||||
|
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
|
|
|
@ -37,6 +37,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void enterEvent(QEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,12 @@ Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||||
, _shadow(this, st::shadowColor)
|
, _shadow(this, st::shadowColor)
|
||||||
, _playback(new Ui::FilledSlider(this, st::mediaPlayerPlayback)) {
|
, _playback(new Ui::FilledSlider(this, st::mediaPlayerPlayback)) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
setMouseTracking(true);
|
||||||
resize(st::wndMinWidth, st::mediaPlayerHeight + st::lineWidth);
|
resize(st::wndMinWidth, st::mediaPlayerHeight + st::lineWidth);
|
||||||
|
|
||||||
|
_nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
_playback->setChangeProgressCallback([this](float64 value) {
|
_playback->setChangeProgressCallback([this](float64 value) {
|
||||||
handleSeekProgress(value);
|
handleSeekProgress(value);
|
||||||
});
|
});
|
||||||
|
@ -226,6 +230,28 @@ void Widget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::leaveEvent(QEvent *e) {
|
||||||
|
updateOverLabelsState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
updateOverLabelsState(e->pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::updateOverLabelsState(QPoint pos) {
|
||||||
|
auto left = getLabelsLeft();
|
||||||
|
auto right = getLabelsRight();
|
||||||
|
auto labels = myrtlrect(left, 0, width() - right - left, height() - st::mediaPlayerPlayback.fullWidth);
|
||||||
|
auto over = labels.contains(pos);
|
||||||
|
updateOverLabelsState(over);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::updateOverLabelsState(bool over) {
|
||||||
|
if (exists()) {
|
||||||
|
instance()->playerWidgetOver().notify(over, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::updatePlayPrevNextPositions() {
|
void Widget::updatePlayPrevNextPositions() {
|
||||||
auto left = st::mediaPlayerPlayLeft;
|
auto left = st::mediaPlayerPlayLeft;
|
||||||
auto top = st::mediaPlayerPlayTop;
|
auto top = st::mediaPlayerPlayTop;
|
||||||
|
@ -238,15 +264,24 @@ void Widget::updatePlayPrevNextPositions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateLabelsGeometry() {
|
int Widget::getLabelsLeft() const {
|
||||||
auto left = st::mediaPlayerPlayLeft + _playPause->width();
|
auto result = st::mediaPlayerPlayLeft + _playPause->width();
|
||||||
if (_previousTrack) {
|
if (_previousTrack) {
|
||||||
left += _previousTrack->width() + st::mediaPlayerPlaySkip + _nextTrack->width() + st::mediaPlayerPlaySkip;
|
result += _previousTrack->width() + st::mediaPlayerPlaySkip + _nextTrack->width() + st::mediaPlayerPlaySkip;
|
||||||
}
|
}
|
||||||
left += st::mediaPlayerPadding;
|
result += st::mediaPlayerPadding;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
auto right = st::mediaPlayerCloseRight + _close->width() + _repeatTrack->width() + _volumeToggle->width();
|
int Widget::getLabelsRight() const {
|
||||||
right += st::mediaPlayerPadding;
|
auto result = st::mediaPlayerCloseRight + _close->width() + _repeatTrack->width() + _volumeToggle->width();
|
||||||
|
result += st::mediaPlayerPadding;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::updateLabelsGeometry() {
|
||||||
|
auto left = getLabelsLeft();
|
||||||
|
auto right = getLabelsRight();
|
||||||
|
|
||||||
auto widthForName = width() - left - right;
|
auto widthForName = width() - left - right;
|
||||||
widthForName -= _timeLabel->width() + 2 * st::normalFont->spacew;
|
widthForName -= _timeLabel->width() + 2 * st::normalFont->spacew;
|
||||||
|
@ -367,12 +402,14 @@ void Widget::handlePlaylistUpdate() {
|
||||||
void Widget::createPrevNextButtons() {
|
void Widget::createPrevNextButtons() {
|
||||||
if (!_previousTrack) {
|
if (!_previousTrack) {
|
||||||
_previousTrack.create(this, st::mediaPlayerPreviousButton);
|
_previousTrack.create(this, st::mediaPlayerPreviousButton);
|
||||||
_nextTrack.create(this, st::mediaPlayerNextButton);
|
_previousTrack->show();
|
||||||
_previousTrack->setClickedCallback([this]() {
|
_previousTrack->setClickedCallback([this]() {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
instance()->previous();
|
instance()->previous();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_nextTrack.create(this, st::mediaPlayerNextButton);
|
||||||
|
_nextTrack->show();
|
||||||
_nextTrack->setClickedCallback([this]() {
|
_nextTrack->setClickedCallback([this]() {
|
||||||
if (exists()) {
|
if (exists()) {
|
||||||
instance()->next();
|
instance()->next();
|
||||||
|
|
|
@ -59,10 +59,18 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleSeekProgress(float64 progress);
|
void handleSeekProgress(float64 progress);
|
||||||
void handleSeekFinished(float64 progress);
|
void handleSeekFinished(float64 progress);
|
||||||
|
|
||||||
|
int getLabelsLeft() const;
|
||||||
|
int getLabelsRight() const;
|
||||||
|
void updateOverLabelsState(QPoint pos);
|
||||||
|
void updateOverLabelsState(bool over);
|
||||||
|
|
||||||
void updatePlayPrevNextPositions();
|
void updatePlayPrevNextPositions();
|
||||||
void updateLabelsGeometry();
|
void updateLabelsGeometry();
|
||||||
void updateRepeatTrackIcon();
|
void updateRepeatTrackIcon();
|
||||||
|
@ -81,6 +89,7 @@ private:
|
||||||
int64 _seekPositionMs = -1;
|
int64 _seekPositionMs = -1;
|
||||||
int64 _lastDurationMs = 0;
|
int64 _lastDurationMs = 0;
|
||||||
QString _time;
|
QString _time;
|
||||||
|
bool _mouseOverLabels = false;
|
||||||
|
|
||||||
class PlayButton;
|
class PlayButton;
|
||||||
ChildWidget<FlatLabel> _nameLabel;
|
ChildWidget<FlatLabel> _nameLabel;
|
||||||
|
|
|
@ -33,7 +33,9 @@ Playback::Playback(Ui::ContinuousSlider *slider) : _slider(slider) {
|
||||||
void Playback::updateState(const AudioPlaybackState &playbackState) {
|
void Playback::updateState(const AudioPlaybackState &playbackState) {
|
||||||
qint64 position = 0, duration = playbackState.duration;
|
qint64 position = 0, duration = playbackState.duration;
|
||||||
|
|
||||||
setDisabled(false);
|
auto wasDisabled = _slider->isDisabled();
|
||||||
|
if (wasDisabled) setDisabled(false);
|
||||||
|
|
||||||
_playing = !(playbackState.state & AudioPlayerStoppedMask);
|
_playing = !(playbackState.state & AudioPlayerStoppedMask);
|
||||||
if (_playing || playbackState.state == AudioPlayerStopped) {
|
if (_playing || playbackState.state == AudioPlayerStopped) {
|
||||||
position = playbackState.position;
|
position = playbackState.position;
|
||||||
|
@ -49,7 +51,7 @@ void Playback::updateState(const AudioPlaybackState &playbackState) {
|
||||||
} else if (duration) {
|
} else if (duration) {
|
||||||
progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.;
|
progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.;
|
||||||
}
|
}
|
||||||
if (duration != _duration || position != _position) {
|
if (duration != _duration || position != _position || wasDisabled) {
|
||||||
auto animated = (duration && _duration && progress > _slider->value());
|
auto animated = (duration && _duration && progress > _slider->value());
|
||||||
_slider->setValue(progress, animated);
|
_slider->setValue(progress, animated);
|
||||||
_position = position;
|
_position = position;
|
||||||
|
|
|
@ -19,6 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
using "basic.style";
|
using "basic.style";
|
||||||
|
using "history/history.style";
|
||||||
|
|
||||||
OverviewFileLayout {
|
OverviewFileLayout {
|
||||||
maxWidth: pixels;
|
maxWidth: pixels;
|
||||||
|
@ -26,6 +27,13 @@ OverviewFileLayout {
|
||||||
songThumbSize: pixels;
|
songThumbSize: pixels;
|
||||||
songNameTop: pixels;
|
songNameTop: pixels;
|
||||||
songStatusTop: pixels;
|
songStatusTop: pixels;
|
||||||
|
songIconBg: color;
|
||||||
|
songOverBg: color;
|
||||||
|
songPause: icon;
|
||||||
|
songPlay: icon;
|
||||||
|
songCancel: icon;
|
||||||
|
songDownload: icon;
|
||||||
|
|
||||||
filePadding: margins;
|
filePadding: margins;
|
||||||
fileThumbSize: pixels;
|
fileThumbSize: pixels;
|
||||||
fileNameTop: pixels;
|
fileNameTop: pixels;
|
||||||
|
@ -61,6 +69,13 @@ overviewFileLayout: OverviewFileLayout {
|
||||||
songThumbSize: msgFileSize;
|
songThumbSize: msgFileSize;
|
||||||
songNameTop: msgFileNameTop;
|
songNameTop: msgFileNameTop;
|
||||||
songStatusTop: msgFileStatusTop;
|
songStatusTop: msgFileStatusTop;
|
||||||
|
songIconBg: msgFileInBg;
|
||||||
|
songOverBg: msgFileInBgOver;
|
||||||
|
songPause: historyFileInPause;
|
||||||
|
songPlay: historyFileInPlay;
|
||||||
|
songCancel: historyFileInCancel;
|
||||||
|
songDownload: historyFileInDownload;
|
||||||
|
|
||||||
filePadding: margins(0px, 3px, 16px, 3px);
|
filePadding: margins(0px, 3px, 16px, 3px);
|
||||||
fileThumbSize: 70px;
|
fileThumbSize: 70px;
|
||||||
fileNameTop: 7px;
|
fileNameTop: 7px;
|
||||||
|
|
|
@ -667,10 +667,10 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
} else if (_a_iconOver.animating()) {
|
} else if (_a_iconOver.animating()) {
|
||||||
_a_iconOver.step(context->ms);
|
_a_iconOver.step(context->ms);
|
||||||
float64 over = a_iconOver.current();
|
float64 over = a_iconOver.current();
|
||||||
p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over));
|
p.setBrush(style::interpolate(_st.songIconBg, _st.songOverBg, over));
|
||||||
} else {
|
} else {
|
||||||
bool over = ClickHandler::showAsActive(loaded ? _openl : (_data->loading() ? _cancell : _openl));
|
bool over = ClickHandler::showAsActive(loaded ? _openl : (_data->loading() ? _cancell : _openl));
|
||||||
p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg);
|
p.setBrush(over ? _st.songOverBg : _st.songIconBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
|
@ -685,13 +685,13 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
|
|
||||||
auto icon = ([showPause, loaded, this, selected] {
|
auto icon = ([showPause, loaded, this, selected] {
|
||||||
if (showPause) {
|
if (showPause) {
|
||||||
return &(selected ? st::historyFileInPauseSelected : st::historyFileInPause);
|
return &(selected ? st::historyFileInPauseSelected : _st.songPause);
|
||||||
} else if (loaded) {
|
} else if (loaded) {
|
||||||
return &(selected ? st::historyFileInPlaySelected : st::historyFileInPlay);
|
return &(selected ? st::historyFileInPlaySelected : _st.songPlay);
|
||||||
} else if (_data->loading()) {
|
} else if (_data->loading()) {
|
||||||
return &(selected ? st::historyFileInCancelSelected : st::historyFileInCancel);
|
return &(selected ? st::historyFileInCancelSelected : _st.songCancel);
|
||||||
}
|
}
|
||||||
return &(selected ? st::historyFileInDownloadSelected : st::historyFileInDownload);
|
return &(selected ? st::historyFileInDownloadSelected : _st.songDownload);
|
||||||
})();
|
})();
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,59 +38,24 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
|
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
|
||||||
|
|
||||||
OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerData *peer, MediaOverviewType type) : QWidget(0)
|
OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerData *peer, MediaOverviewType type) : TWidget(nullptr)
|
||||||
, _overview(overview)
|
, _overview(overview)
|
||||||
, _scroll(scroll)
|
, _scroll(scroll)
|
||||||
, _resizeIndex(-1)
|
|
||||||
, _resizeSkip(0)
|
|
||||||
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
|
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
|
||||||
, _type(type)
|
, _type(type)
|
||||||
, _reversed(_type != OverviewFiles && _type != OverviewLinks)
|
, _reversed(_type != OverviewFiles && _type != OverviewLinks)
|
||||||
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
|
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
|
||||||
, _history(App::history(_peer->id))
|
, _history(App::history(_peer->id))
|
||||||
, _channel(peerToChannel(_peer->id))
|
, _channel(peerToChannel(_peer->id))
|
||||||
, _selMode(false)
|
|
||||||
, _rowsLeft(0)
|
|
||||||
, _rowWidth(st::msgMinWidth)
|
, _rowWidth(st::msgMinWidth)
|
||||||
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
|
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
|
||||||
, _cancelSearch(this, st::btnCancelSearch)
|
, _cancelSearch(this, st::btnCancelSearch)
|
||||||
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
, _itemsToBeLoaded(LinksOverviewPerPage * 2)
|
||||||
, _photosInRow(1)
|
, _width(st::wndMinWidth) {
|
||||||
, _inSearch(false)
|
|
||||||
, _searchFull(false)
|
|
||||||
, _searchFullMigrated(false)
|
|
||||||
, _searchRequest(0)
|
|
||||||
, _lastSearchId(0)
|
|
||||||
, _lastSearchMigratedId(0)
|
|
||||||
, _searchedCount(0)
|
|
||||||
, _width(st::wndMinWidth)
|
|
||||||
, _height(0)
|
|
||||||
, _minHeight(0)
|
|
||||||
, _marginTop(0)
|
|
||||||
, _marginBottom(0)
|
|
||||||
, _cursor(style::cur_default)
|
|
||||||
, _cursorState(HistoryDefaultCursorState)
|
|
||||||
, _dragAction(NoDrag)
|
|
||||||
, _dragItem(0)
|
|
||||||
, _selectedMsgId(0)
|
|
||||||
, _dragItemIndex(-1)
|
|
||||||
, _mousedItem(0)
|
|
||||||
, _mousedItemIndex(-1)
|
|
||||||
, _dragWasInactive(false)
|
|
||||||
, _dragSelFrom(0)
|
|
||||||
, _dragSelTo(0)
|
|
||||||
, _dragSelecting(false)
|
|
||||||
, _touchScroll(false)
|
|
||||||
, _touchSelect(false)
|
|
||||||
, _touchInProgress(false)
|
|
||||||
, _touchScrollState(TouchScrollManual)
|
|
||||||
, _touchPrevPosValid(false)
|
|
||||||
, _touchWaitingAcceleration(false)
|
|
||||||
, _touchSpeedTime(0)
|
|
||||||
, _touchAccelerationTime(0)
|
|
||||||
, _touchTime(0)
|
|
||||||
, _menu(0) {
|
|
||||||
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
||||||
|
subscribe(Global::RefItemRemoved(), [this](HistoryItem *item) {
|
||||||
|
itemRemoved(item);
|
||||||
|
});
|
||||||
|
|
||||||
resize(_width, st::wndMinHeight);
|
resize(_width, st::wndMinHeight);
|
||||||
|
|
||||||
|
@ -1733,6 +1698,10 @@ void OverviewInner::changingMsgId(HistoryItem *row, MsgId newId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewInner::itemRemoved(HistoryItem *item) {
|
void OverviewInner::itemRemoved(HistoryItem *item) {
|
||||||
|
if (_history != item->history() && _migrated != item->history()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MsgId msgId = (item->history() == _migrated) ? -item->id : item->id;
|
MsgId msgId = (item->history() == _migrated) ? -item->id : item->id;
|
||||||
if (_dragItem == msgId) {
|
if (_dragItem == msgId) {
|
||||||
dragActionCancel();
|
dragActionCancel();
|
||||||
|
@ -1741,13 +1710,13 @@ void OverviewInner::itemRemoved(HistoryItem *item) {
|
||||||
_selectedMsgId = 0;
|
_selectedMsgId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectedItems::iterator i = _selected.find(msgId);
|
auto i = _selected.find(msgId);
|
||||||
if (i != _selected.cend()) {
|
if (i != _selected.cend()) {
|
||||||
_selected.erase(i);
|
_selected.erase(i);
|
||||||
_overview->updateTopBarSelection();
|
_overview->updateTopBarSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutItems::iterator j = _layoutItems.find(item);
|
auto j = _layoutItems.find(item);
|
||||||
if (j != _layoutItems.cend()) {
|
if (j != _layoutItems.cend()) {
|
||||||
int32 index = _items.indexOf(j.value());
|
int32 index = _items.indexOf(j.value());
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -2218,10 +2187,6 @@ void OverviewWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::itemRemoved(HistoryItem *row) {
|
|
||||||
_inner.itemRemoved(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OverviewWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
|
void OverviewWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
|
||||||
_inner.fillSelectedItems(sel, forDelete);
|
_inner.fillSelectedItems(sel, forDelete);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ class PlainShadow;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
class OverviewWidget;
|
class OverviewWidget;
|
||||||
class OverviewInner : public QWidget, public AbstractTooltipShower, public RPCSender, private base::Subscriber {
|
class OverviewInner : public TWidget, public AbstractTooltipShower, public RPCSender, private base::Subscriber {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -73,7 +73,6 @@ public:
|
||||||
void mediaOverviewUpdated();
|
void mediaOverviewUpdated();
|
||||||
void changingMsgId(HistoryItem *row, MsgId newId);
|
void changingMsgId(HistoryItem *row, MsgId newId);
|
||||||
void repaintItem(const HistoryItem *msg);
|
void repaintItem(const HistoryItem *msg);
|
||||||
void itemRemoved(HistoryItem *item);
|
|
||||||
|
|
||||||
void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const;
|
void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const;
|
||||||
void clearSelectedItems(bool onlyTextSelection = false);
|
void clearSelectedItems(bool onlyTextSelection = false);
|
||||||
|
@ -124,6 +123,7 @@ public slots:
|
||||||
void onNeedSearchMessages();
|
void onNeedSearchMessages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
MsgId complexMsgId(const HistoryItem *item) const;
|
MsgId complexMsgId(const HistoryItem *item) const;
|
||||||
|
|
||||||
bool itemMigrated(MsgId msgId) const;
|
bool itemMigrated(MsgId msgId) const;
|
||||||
|
@ -152,7 +152,8 @@ private:
|
||||||
|
|
||||||
OverviewWidget *_overview;
|
OverviewWidget *_overview;
|
||||||
ScrollArea *_scroll;
|
ScrollArea *_scroll;
|
||||||
int32 _resizeIndex, _resizeSkip;
|
int _resizeIndex = -1;
|
||||||
|
int _resizeSkip = 0;
|
||||||
|
|
||||||
PeerData *_peer;
|
PeerData *_peer;
|
||||||
MediaOverviewType _type;
|
MediaOverviewType _type;
|
||||||
|
@ -160,10 +161,11 @@ private:
|
||||||
History *_migrated, *_history;
|
History *_migrated, *_history;
|
||||||
ChannelId _channel;
|
ChannelId _channel;
|
||||||
|
|
||||||
bool _selMode;
|
bool _selMode = false;
|
||||||
TextSelection itemSelectedValue(int32 index) const;
|
TextSelection itemSelectedValue(int32 index) const;
|
||||||
|
|
||||||
int32 _rowsLeft, _rowWidth;
|
int _rowsLeft = 0;
|
||||||
|
int _rowWidth = 0;
|
||||||
|
|
||||||
typedef QVector<Overview::Layout::AbstractItem*> Items;
|
typedef QVector<Overview::Layout::AbstractItem*> Items;
|
||||||
Items _items;
|
Items _items;
|
||||||
|
@ -181,15 +183,18 @@ private:
|
||||||
int32 _itemsToBeLoaded;
|
int32 _itemsToBeLoaded;
|
||||||
|
|
||||||
// photos
|
// photos
|
||||||
int32 _photosInRow;
|
int32 _photosInRow = 1;
|
||||||
|
|
||||||
QTimer _searchTimer;
|
QTimer _searchTimer;
|
||||||
QString _searchQuery;
|
QString _searchQuery;
|
||||||
bool _inSearch, _searchFull, _searchFullMigrated;
|
bool _inSearch = false;
|
||||||
mtpRequestId _searchRequest;
|
bool _searchFull = false;
|
||||||
|
bool _searchFullMigrated = false;
|
||||||
|
mtpRequestId _searchRequest = 0;
|
||||||
History::MediaOverview _searchResults;
|
History::MediaOverview _searchResults;
|
||||||
MsgId _lastSearchId, _lastSearchMigratedId;
|
MsgId _lastSearchId = 0;
|
||||||
int32 _searchedCount;
|
MsgId _lastSearchMigratedId = 0;
|
||||||
|
int _searchedCount = 0;
|
||||||
enum SearchRequestType {
|
enum SearchRequestType {
|
||||||
SearchFromStart,
|
SearchFromStart,
|
||||||
SearchFromOffset,
|
SearchFromOffset,
|
||||||
|
@ -205,13 +210,17 @@ private:
|
||||||
typedef QMap<mtpRequestId, QString> SearchQueries;
|
typedef QMap<mtpRequestId, QString> SearchQueries;
|
||||||
SearchQueries _searchQueries;
|
SearchQueries _searchQueries;
|
||||||
|
|
||||||
int32 _width, _height, _minHeight, _marginTop, _marginBottom;
|
int _width = 0;
|
||||||
|
int _height = 0;
|
||||||
|
int _minHeight = 0;
|
||||||
|
int _marginTop = 0;
|
||||||
|
int _marginBottom = 0;
|
||||||
|
|
||||||
QTimer _linkTipTimer;
|
QTimer _linkTipTimer;
|
||||||
|
|
||||||
// selection support, like in HistoryWidget
|
// selection support, like in HistoryWidget
|
||||||
Qt::CursorShape _cursor;
|
style::cursor _cursor = style::cur_default;
|
||||||
HistoryCursorState _cursorState;
|
HistoryCursorState _cursorState = HistoryDefaultCursorState;
|
||||||
using SelectedItems = QMap<MsgId, TextSelection>;
|
using SelectedItems = QMap<MsgId, TextSelection>;
|
||||||
SelectedItems _selected;
|
SelectedItems _selected;
|
||||||
enum DragAction {
|
enum DragAction {
|
||||||
|
@ -221,32 +230,40 @@ private:
|
||||||
PrepareSelect = 0x03,
|
PrepareSelect = 0x03,
|
||||||
Selecting = 0x04,
|
Selecting = 0x04,
|
||||||
};
|
};
|
||||||
DragAction _dragAction;
|
DragAction _dragAction = NoDrag;
|
||||||
QPoint _dragStartPos, _dragPos;
|
QPoint _dragStartPos, _dragPos;
|
||||||
MsgId _dragItem, _selectedMsgId;
|
MsgId _dragItem = 0;
|
||||||
int32 _dragItemIndex;
|
MsgId _selectedMsgId = 0;
|
||||||
MsgId _mousedItem;
|
int _dragItemIndex = -1;
|
||||||
int32 _mousedItemIndex;
|
MsgId _mousedItem = 0;
|
||||||
|
int _mousedItemIndex = -1;
|
||||||
uint16 _dragSymbol;
|
uint16 _dragSymbol;
|
||||||
bool _dragWasInactive;
|
bool _dragWasInactive = false;
|
||||||
|
|
||||||
ClickHandlerPtr _contextMenuLnk;
|
ClickHandlerPtr _contextMenuLnk;
|
||||||
|
|
||||||
MsgId _dragSelFrom, _dragSelTo;
|
MsgId _dragSelFrom = 0;
|
||||||
int32 _dragSelFromIndex, _dragSelToIndex;
|
MsgId _dragSelTo = 0;
|
||||||
bool _dragSelecting;
|
int _dragSelFromIndex = -1;
|
||||||
|
int _dragSelToIndex = -1;
|
||||||
|
bool _dragSelecting = false;
|
||||||
|
|
||||||
bool _touchScroll, _touchSelect, _touchInProgress;
|
bool _touchScroll = false;
|
||||||
|
bool _touchSelect = false;
|
||||||
|
bool _touchInProgress = false;
|
||||||
QPoint _touchStart, _touchPrevPos, _touchPos;
|
QPoint _touchStart, _touchPrevPos, _touchPos;
|
||||||
QTimer _touchSelectTimer;
|
QTimer _touchSelectTimer;
|
||||||
|
|
||||||
TouchScrollState _touchScrollState;
|
TouchScrollState _touchScrollState = TouchScrollManual;
|
||||||
bool _touchPrevPosValid, _touchWaitingAcceleration;
|
bool _touchPrevPosValid = false;
|
||||||
|
bool _touchWaitingAcceleration = false;
|
||||||
QPoint _touchSpeed;
|
QPoint _touchSpeed;
|
||||||
uint64 _touchSpeedTime, _touchAccelerationTime, _touchTime;
|
uint64 _touchSpeedTime = 0;
|
||||||
|
uint64 _touchAccelerationTime = 0;
|
||||||
|
uint64 _touchTime = 0;
|
||||||
QTimer _touchScrollTimer;
|
QTimer _touchScrollTimer;
|
||||||
|
|
||||||
PopupMenu *_menu;
|
PopupMenu *_menu = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OverviewWidget : public TWidget, public RPCSender {
|
class OverviewWidget : public TWidget, public RPCSender {
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Settings {
|
||||||
NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_notify)) {
|
NotificationsWidget::NotificationsWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_notify)) {
|
||||||
createControls();
|
createControls();
|
||||||
|
|
||||||
subscribe(Global::RefNotifySettingsChanged(), [this](const Notify::ChangeType &type) {
|
subscribe(Global::RefNotifySettingsChanged(), [this](Notify::ChangeType type) {
|
||||||
if (type == Notify::ChangeType::DesktopEnabled) {
|
if (type == Notify::ChangeType::DesktopEnabled) {
|
||||||
desktopEnabledUpdated();
|
desktopEnabledUpdated();
|
||||||
} else if (type == Notify::ChangeType::ViewParams) {
|
} else if (type == Notify::ChangeType::ViewParams) {
|
||||||
|
|
|
@ -103,18 +103,8 @@ TitleWidget::TitleWidget(QWidget *parent) : TWidget(parent)
|
||||||
|
|
||||||
subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); });
|
subscribe(Adaptive::Changed(), [this]() { updateAdaptiveLayout(); });
|
||||||
if (Media::Player::exists()) {
|
if (Media::Player::exists()) {
|
||||||
subscribe(Media::Player::instance()->createdNotifier(), [this](const Media::Player::PanelEvent &e) {
|
subscribe(Media::Player::instance()->usePanelPlayer(), [this](bool usePanel) {
|
||||||
if (!_player) {
|
updatePlayerButton(usePanel);
|
||||||
_player.create(this);
|
|
||||||
updateControlsVisibility();
|
|
||||||
}
|
|
||||||
_player->installEventFilter(e.panel);
|
|
||||||
});
|
|
||||||
subscribe(Media::Player::instance()->destroyedNotifier(), [this](const Media::Player::PanelEvent &e) {
|
|
||||||
if (_player) {
|
|
||||||
_player.destroyDelayed();
|
|
||||||
updateControlsVisibility();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +169,15 @@ void TitleWidget::onAbout() {
|
||||||
Ui::showLayer(new AboutBox());
|
Ui::showLayer(new AboutBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TitleWidget::updatePlayerButton(bool usePanel) {
|
||||||
|
if (usePanel && !_player) {
|
||||||
|
_player.create(this);
|
||||||
|
} else if (!usePanel && _player) {
|
||||||
|
_player.destroyDelayed();
|
||||||
|
}
|
||||||
|
updateControlsVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
void TitleWidget::updateControlsPosition() {
|
void TitleWidget::updateControlsPosition() {
|
||||||
QPoint p(width() - ((cPlatform() == dbipWindows && lastMaximized) ? 0 : st::sysBtnDelta), 0);
|
QPoint p(width() - ((cPlatform() == dbipWindows && lastMaximized) ? 0 : st::sysBtnDelta), 0);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ class MainWindow;
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Player {
|
namespace Player {
|
||||||
class TitleButton;
|
class TitleButton;
|
||||||
class PanelEvent;
|
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
} // namespace Media
|
} // namespace Media
|
||||||
class AudioMsgId;
|
class AudioMsgId;
|
||||||
|
@ -65,6 +64,7 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updatePlayerButton(bool usePanel);
|
||||||
void updateAdaptiveLayout();
|
void updateAdaptiveLayout();
|
||||||
void updateRestartButtonVisibility();
|
void updateRestartButtonVisibility();
|
||||||
void updateMenuButtonsVisibility();
|
void updateMenuButtonsVisibility();
|
||||||
|
|
|
@ -39,6 +39,9 @@ public:
|
||||||
void setValue(float64 value, bool animated);
|
void setValue(float64 value, bool animated);
|
||||||
void setFadeOpacity(float64 opacity);
|
void setFadeOpacity(float64 opacity);
|
||||||
void setDisabled(bool disabled);
|
void setDisabled(bool disabled);
|
||||||
|
bool isDisabled() const {
|
||||||
|
return _disabled;
|
||||||
|
}
|
||||||
|
|
||||||
using Callback = base::lambda_unique<void(float64)>;
|
using Callback = base::lambda_unique<void(float64)>;
|
||||||
void setChangeProgressCallback(Callback &&callback) {
|
void setChangeProgressCallback(Callback &&callback) {
|
||||||
|
@ -71,9 +74,6 @@ protected:
|
||||||
float64 getCurrentOverFactor(uint64 ms) {
|
float64 getCurrentOverFactor(uint64 ms) {
|
||||||
return _disabled ? 0. : _a_over.current(ms, _over ? 1. : 0.);
|
return _disabled ? 0. : _a_over.current(ms, _over ? 1. : 0.);
|
||||||
}
|
}
|
||||||
bool isDisabled() const {
|
|
||||||
return _disabled;
|
|
||||||
}
|
|
||||||
Direction getDirection() const {
|
Direction getDirection() const {
|
||||||
return _direction;
|
return _direction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ Manager::Manager() {
|
||||||
notification->updatePeerPhoto();
|
notification->updatePeerPhoto();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
subscribe(Global::RefNotifySettingsChanged(), [this](const Notify::ChangeType &change) {
|
subscribe(Global::RefNotifySettingsChanged(), [this](Notify::ChangeType change) {
|
||||||
settingsChanged(change);
|
settingsChanged(change);
|
||||||
});
|
});
|
||||||
_inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); });
|
_inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); });
|
||||||
|
@ -89,7 +89,7 @@ bool Manager::hasReplyingNotification() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::settingsChanged(const Notify::ChangeType &change) {
|
void Manager::settingsChanged(Notify::ChangeType change) {
|
||||||
if (change == Notify::ChangeType::Corner) {
|
if (change == Notify::ChangeType::Corner) {
|
||||||
auto startPosition = notificationStartPosition();
|
auto startPosition = notificationStartPosition();
|
||||||
auto shiftDirection = notificationShiftDirection();
|
auto shiftDirection = notificationShiftDirection();
|
||||||
|
|
|
@ -82,7 +82,7 @@ private:
|
||||||
|
|
||||||
void moveWidgets();
|
void moveWidgets();
|
||||||
void changeNotificationHeight(Notification *widget, int newHeight);
|
void changeNotificationHeight(Notification *widget, int newHeight);
|
||||||
void settingsChanged(const Notify::ChangeType &change);
|
void settingsChanged(Notify::ChangeType change);
|
||||||
|
|
||||||
bool hasReplyingNotification() const;
|
bool hasReplyingNotification() const;
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,7 @@
|
||||||
'<(src_loc)/core/single_timer.cpp',
|
'<(src_loc)/core/single_timer.cpp',
|
||||||
'<(src_loc)/core/single_timer.h',
|
'<(src_loc)/core/single_timer.h',
|
||||||
'<(src_loc)/core/stl_subset.h',
|
'<(src_loc)/core/stl_subset.h',
|
||||||
|
'<(src_loc)/core/type_traits.h',
|
||||||
'<(src_loc)/core/utils.cpp',
|
'<(src_loc)/core/utils.cpp',
|
||||||
'<(src_loc)/core/utils.h',
|
'<(src_loc)/core/utils.h',
|
||||||
'<(src_loc)/core/vector_of_moveable.h',
|
'<(src_loc)/core/vector_of_moveable.h',
|
||||||
|
|
Loading…
Add table
Reference in a new issue